diff --git a/content/zh/_index.html b/content/zh/_index.html index 9405f2de0e457..1b0ff0170060c 100644 --- a/content/zh/_index.html +++ b/content/zh/_index.html @@ -1,61 +1,82 @@ --- title: "生产级别的容器编排系统" abstract: "自动化的容器部署、扩展和管理" -cid: "home" +cid: home --- {{< deprecationwarning >}} {{< blocks/section id="oceanNodes" >}} {{% blocks/feature image="flower" %}} -### [Kubernetes (K8s)]({{< relref "/docs/concepts/overview/what-is-kubernetes" >}}) -是一个开源系统,用于容器化应用的自动部署、扩缩和管理。 -Kubernetes 将构成应用的容器按逻辑单位进行分组以便于管理和发现。 -Kubernetes 基于 [谷歌公司在运行生产负载上的 15 年经验](http://queue.acm.org/detail.cfm?id=2898444) -打造,并融合了来自社区的最佳建议与实践。 + +### [Kubernetes]({{< relref "/docs/concepts/overview/what-is-kubernetes" >}}) 是用于自动部署,扩展和管理容器化应用程序的开源系统。 + + + +它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。Kubernetes 源自[Google 15 年生产环境的运维经验](http://queue.acm.org/detail.cfm?id=2898444),同时凝聚了社区的最佳创意和实践。 + {{% /blocks/feature %}} {{% blocks/feature image="scalable" %}} -#### 星际规模 -基于一定的规则原理,谷歌公司每周能够运行数十亿的容器;通过遵循相同的设计, -Kubernetes 能够在保持现有运维团队规模的前提下完成集群的弹性伸缩。 + +#### 星际尺度 + + + +Google 每周运行数十亿个容器,Kubernetes 基于与之相同的原则来设计,能够在不扩张运维团队的情况下进行规模扩展。 {{% /blocks/feature %}} {{% blocks/feature image="blocks" %}} -#### 永不过时 -无论是在本地测试还是支撑全球化企业业务,Kubernetes 的灵活性使得其能够与您一起成长。 -无论您的需求多么复杂,Kubernetes 都能助您始终如一地、轻而易举地交付应用。 + +#### 处处适用 + + + +无论是本地测试,还是跨国公司,Kubernetes 的灵活性都能让你在应对复杂系统时得心应手。 {{% /blocks/feature %}} {{% blocks/feature image="suitcase" %}} -#### 随处运行 -作为一个开源系统,Kubernetes 使您能够自由地获得内部云、混合云或公有云基础设施所提供的便利, -并根据需要轻松地迁移工作负载。 + +#### 永不过时 + + + +Kubernetes 是开源系统,可以自由地部署在企业内部,私有云、混合云或公有云,让您轻松地做出合适的选择。 {{% /blocks/feature %}} {{< /blocks/section >}} {{< blocks/section id="video" background-image="kub_video_banner_homepage" >}} +
-

将超过 150 个微服务迁移到 Kubernetes 时遇到的挑战

-

Sarah Wells, Technical Director for Operations and Reliability, Financial Times

- -
-
-
- 参加 2019 年 11 月 18 日的 San Diego KubeCon -
-
-
-
- 参加 2020 年 3 月 30 日的 Amsterdam KubeCon + +

将 150+ 微服务迁移到 Kubernetes 上的挑战

+ +

Sarah Wells, 运营和可靠性技术总监, 金融时报

+ +
+
+
+ + 参加11月13日到15日的上海 KubeCon +
+
+
+
+ + 参加12月11日到13日的西雅图 KubeCon
diff --git a/content/zh/_redirects b/content/zh/_redirects new file mode 100644 index 0000000000000..a38fbcc91be78 --- /dev/null +++ b/content/zh/_redirects @@ -0,0 +1 @@ +/zh/docs/ /zh/docs/home/ 301 diff --git a/content/zh/blog/_posts/2015-03-00-Kubernetes-Gathering-Videos.md b/content/zh/blog/_posts/2015-03-00-Kubernetes-Gathering-Videos.md new file mode 100644 index 0000000000000..2576296c644b6 --- /dev/null +++ b/content/zh/blog/_posts/2015-03-00-Kubernetes-Gathering-Videos.md @@ -0,0 +1,27 @@ +--- + +title: " Kubernetes 采集视频 " +date: 2015-03-23 +slug: kubernetes-gathering-videos +url: /blog/2015/03/Kubernetes-Gathering-Videos +--- + + + + + +如果你错过了上个月在旧金山举行的 Kubernetes 大会,不要害怕!以下是在 YouTube 上组织成播放列表的晚间演示文稿中的视频。 + +[![Kubernetes Gathering](https://img.youtube.com/vi/q8lGZCKktYo/0.jpg)](https://www.youtube.com/playlist?list=PL69nYSiGNLP2FBVvSLHpJE8_6hRHW8Kxe) diff --git a/content/zh/blog/_posts/2015-03-00-Weekly-Kubernetes-Community-Hangout.md b/content/zh/blog/_posts/2015-03-00-Weekly-Kubernetes-Community-Hangout.md new file mode 100644 index 0000000000000..6a345d4950b2d --- /dev/null +++ b/content/zh/blog/_posts/2015-03-00-Weekly-Kubernetes-Community-Hangout.md @@ -0,0 +1,186 @@ +--- +title: " Kubernetes 社区每周聚会笔记 - 2015年3月27日 " +date: 2015-03-28 +slug: weekly-kubernetes-community-hangout +url: /blog/2015/03/Weekly-Kubernetes-Community-Hangout +--- + + + + +每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。 + + +日程安排: + + + +\- Andy - 演示远程执行和端口转发 + +\- Quinton - 联邦集群 - 延迟 + +\- Clayton - 围绕 Kubernetes 的 UI 代码共享和协作 + + +从会议指出: + + + +1\. Andy 从 RedHat: + + + +* 演示远程执行 + + + + * kubectl exec -p $POD -- $CMD + + * 作为代理与主机建立连接,找出 pod 所在的节点,代理与 kubelet 的连接,这一点很有趣。通过 nsenter。 + + * 使用 SPDY 通过 HTTP 进行多路复用流式传输 + + * 还有互动模式: + + * 假设第一个容器,可以使用 -c $CONTAINER 一个特定的。 + + * 如果在容器中预先安装了 gdb,则可以交互地将其附加到正在运行的进程中 + + * backtrace、symbol tbles、print 等。 使用gdb可以做的大多数事情。 + + * 也可以用精心制作的参数在上面运行 rsync 或者在容器内设置 sshd。 + + * 一些聊天反馈: + + + +* Andy 还演示了端口转发 +* nnsenter 与 docker exec + + + + * 想要在主机的控制下注入二进制文件,类似于预启动钩子 + + * socat、nsenter,任何预启动钩子需要的 + + + +* 如果能在博客上发表这方面的文章就太好了 +* wheezy 中的 nginx 版本太旧,无法支持所需的主代理功能 + + + +2\. Clayton: 我们的社区组织在哪里,例如 kubernetes UI 组件? + +* google-containers-ui IRC 频道,邮件列表。 +* Tim: google-containers 前缀是历史的,应该只做 "kubernetes-ui" +* 也希望将设计资源投入使用,并且 bower 期望自己的仓库。 +* 通用协议 + + + +3\. Brian Grant: + +* 测试 v1beta3,准备进入。 +* Paul 力于改变命令行的内容。 +* 下周初至中旬,尝试默认启用v1beta3 ? +* 对于任何其他更改,请发出文件并抄送 thockin。 + + + +4\. 一般认为30分钟比60分钟好 + + + +* 不应该为了填满时间而人为地延长。 diff --git a/content/zh/blog/_posts/2015-03-00-Welcome-To-Kubernetes-Blog.md b/content/zh/blog/_posts/2015-03-00-Welcome-To-Kubernetes-Blog.md new file mode 100644 index 0000000000000..3e3b5f6d3dbd8 --- /dev/null +++ b/content/zh/blog/_posts/2015-03-00-Welcome-To-Kubernetes-Blog.md @@ -0,0 +1,62 @@ +--- +title: 欢迎来到 Kubernetes 博客! +date: 2015-03-20 +slug: welcome-to-kubernetes-blog +url: /blog/2015/03/Welcome-To-Kubernetes-Blog +--- + + + + +欢迎来到新的 Kubernetes 博客。关注此博客,了解 Kubernetes 开源项目。我们计划不时发布发布说明,操作方法文章,活动,甚至一些非常有趣的话题。 + + +如果您正在使用 Kubernetes 或为该项目做出贡献并想要发帖子,[请告诉我](mailto:kitm@google.com)。 + + +首先,以下是 Kubernetes 最近在其他网站上发布的文章摘要: + + + +- [使用 Vitess 和 Kubernetes 在云中扩展 MySQL](http://googlecloudplatform.blogspot.com/2015/03/scaling-MySQL-in-the-cloud-with-Vitess-and-Kubernetes.html) +- [虚拟机上的容器群集](http://googlecloudplatform.blogspot.com/2015/02/container-clusters-on-vms.html) +- [想知道的关于 kubernetes 的一切,却又不敢问](http://googlecloudplatform.blogspot.com/2015/01/everything-you-wanted-to-know-about-Kubernetes-but-were-afraid-to-ask.html) +- [什么构成容器集群?](http://googlecloudplatform.blogspot.com/2015/01/what-makes-a-container-cluster.html) +- [将 OpenStack 和 Kubernetes 与 Murano 集成](https://www.mirantis.com/blog/integrating-openstack-and-kubernetes-with-murano/) +- [容器介绍,Kubernetes 以及现代云计算的发展轨迹](http://googlecloudplatform.blogspot.com/2015/01/in-coming-weeks-we-will-be-publishing.html) +- [什么是 Kubernetes 以及如何使用它?](http://www.centurylinklabs.com/what-is-kubernetes-and-how-to-use-it/) +- [OpenShift V3,Docker 和 Kubernetes 策略](https://blog.openshift.com/v3-docker-kubernetes-interview/) +- [Kubernetes 简介](https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes) + + +快乐的云计算! + + + - Kit Merker - Google 云平台产品经理 diff --git a/content/zh/blog/_posts/2015-04-00-Kubernetes-Release-0150.md b/content/zh/blog/_posts/2015-04-00-Kubernetes-Release-0150.md new file mode 100644 index 0000000000000..d7071e2377d8f --- /dev/null +++ b/content/zh/blog/_posts/2015-04-00-Kubernetes-Release-0150.md @@ -0,0 +1,176 @@ +--- +title: " Kubernetes Release: 0.15.0 " +date: 2015-04-16 +slug: kubernetes-release-0150 +url: /blog/2015/04/Kubernetes-Release-0150 +--- + + + +Release 说明: + + + +* 启用 1beta3 API 并将其设置为默认 API 版本 ([#6098][1]) +* 增加了多端口服务([#6182][2]) + * 新入门指南 + * 多节点本地启动指南 ([#6505][3]) + * Google 云平台上的 Mesos ([#5442][4]) + * Ansible 安装说明 ([#6237][5]) +* 添加了一个控制器框架 ([#5270][6], [#5473][7]) +* Kubelet 现在监听一个安全的 HTTPS 端口 ([#6380][8]) +* 使 kubectl 错误更加友好 ([#6338][9]) +* apiserver 现在支持客户端 cert 身份验证 ([#6190][10]) +* apiserver 现在限制了它处理的并发请求的数量 ([#6207][11]) +* 添加速度限制删除 pod ([#6355][12]) +* 将平衡资源分配算法作为优先级函数实现在调度程序包中 ([#6150][13]) +* 从主服务器启用日志收集功能 ([#6396][14]) +* 添加了一个 api 端口来从 Pod 中提取日志 ([#6497][15]) +* 为调度程序添加了延迟指标 ([#6368][16]) +* 为 REST 客户端添加了延迟指标 ([#6409][17]) + + + +* etcd 现在在 master 上的一个 pod 中运行 ([#6221][18]) +* nginx 现在在 master上的容器中运行 ([#6334][19]) +* 开始为主组件构建 Docker 镜像 ([#6326][20]) +* 更新了 GCE 程序以使用 gcloud 0.9.54 ([#6270][21]) +* 更新了 AWS 程序来修复区域与区域语义 ([#6011][22]) +* 记录镜像 GC 失败时的事件 ([#6091][23]) +* 为 kubernetes 客户端添加 QPS 限制器 ([#6203][24]) +* 减少运行 make release 所需的时间 ([#6196][25]) +* 新卷的支持 + * 添加 iscsi 卷插件 ([#5506][26]) + * 添加 glusterfs 卷插件 ([#6174][27]) + * AWS EBS 卷支持 ([#5138][28]) +* 更新到 heapster 版本到 v0.10.0 ([#6331][29]) +* 更新到 etcd 2.0.9 ([#6544][30]) +* 更新到 Kibana 到 v1.2 ([#6426][31]) +* 漏洞修复 + * 如果服务的公共 IP 发生变化,Kube-proxy现在会更新iptables规则 ([#6123][32]) + * 如果初始创建失败,则重试 kube-addons 创建 ([#6200][33]) + * 使 kube-proxy 对耗尽文件描述符更具弹性 ([#6727][34]) + + +要下载,请访问 https://github.com/GoogleCloudPlatform/kubernetes/releases/tag/v0.15.0 + + +[1]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6098 "在 master 中默认启用 v1beta3 api 版本" +[2]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6182 "实现多端口服务" +[3]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6505 "Docker 多节点" +[4]: https://github.com/GoogleCloudPlatform/kubernetes/pull/5442 "谷歌云平台上 Mesos 入门指南" +[5]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6237 "示例 ansible 设置仓库" +[6]: https://github.com/GoogleCloudPlatform/kubernetes/pull/5270 "控制器框架" +[7]: https://github.com/GoogleCloudPlatform/kubernetes/pull/5473 "添加 DeltaFIFO(控制器框架块)" +[8]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6380 "将 kubelet 配置为使用 HTTPS (获得 2)" +[9]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6338 "返回用于配置验证的类型化错误,并简化错误" +[10]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6190 "添加客户端证书认证" +[11]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6207 "为服务器处理的正在运行的请求数量添加一个限制。" +[12]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6355 "添加速度限制删除 pod" +[13]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6150 "将均衡资源分配算法作为优先级函数实现在调度程序包中。" +[14]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6396 "启用主服务器收集日志。" +[15]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6497 "pod 子日志资源" +[16]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6368 "将基本延迟指标添加到调度程序。" +[17]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6409 "向 REST 客户端添加延迟指标" +[18]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6221 "在 pod 中运行 etcd 2.0.5" +[19]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6334 "添加一个 nginx docker 镜像用于主程序。" +[20]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6326 "为主组件创建 Docker 镜像" +[21]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6270 "gcloud 0.9.54 的更新" + + +[22]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6011 "修复 AWS 区域 与 zone" +[23]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6091 "记录镜像 GC 失败时的事件。" +[24]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6203 "向 kubernetes 客户端添加 QPS 限制器。" +[25]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6196 "在 `make release` 的构建和打包阶段并行化架构" +[26]: https://github.com/GoogleCloudPlatform/kubernetes/pull/5506 "添加 iscsi 卷插件" +[27]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6174 "实现 glusterfs 卷插件" +[28]: https://github.com/GoogleCloudPlatform/kubernetes/pull/5138 "AWS EBS 卷支持" +[29]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6331 "将 heapster 版本更新到 v0.10.0" +[30]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6544 "构建 etcd 镜像(版本 2.0.9),并将 kubernetes 集群升级到新版本" +[31]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6426 "更新 Kibana 到 v1.2,它对 Elasticsearch 的位置进行了参数化" +[32]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6123 "修复了 kube-proxy 中的一个错误,如果一个服务的公共 ip 发生变化,它不会更新 iptables 规则" +[33]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6200 "如果 kube-addons 创建失败,请重试 kube-addons 创建。" +[34]: https://github.com/GoogleCloudPlatform/kubernetes/pull/6727 "pkg/proxy: fd 用完后引起恐慌" + diff --git a/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_17.md b/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_17.md new file mode 100644 index 0000000000000..e71b8d17be7e8 --- /dev/null +++ b/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_17.md @@ -0,0 +1,287 @@ +--- +title: " Kubernetes 社区每周聚会笔记- 2015年4月17日 " +date: 2015-04-17 +slug: weekly-kubernetes-community-hangout_17 +url: /blog/2015/04/Weekly-Kubernetes-Community-Hangout_17 +--- + + + + +每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。 + + +议程 + +* Mesos 集成 +* 高可用性(HA) +* 向 e2e 添加性能和分析详细信息以跟踪回归 +* 客户端版本化 + + +笔记 + + + +* Mesos 集成 + + * Mesos 集成提案: + + * 没有阻塞集成的因素。 + + * 文档需要更新。 + + + +* HA + + * 提案今天应该会提交。 + + * Etcd 集群。 + + * apiserver 负载均衡。 + + * 控制器管理器和其他主组件的冷备用。 + + + +* 向 e2e 添加性能和分析详细信息以跟踪回归 + + * 希望红色为性能回归 + + * 需要公共数据库才能发布数据 + + * 查看 + + * Justin 致力于多平台 e2e 仪表盘 + + + +* 客户端版本化 + + * + + * + + * 客户端库当前使用内部 API 对象。 + + * 尽管没有人反映频繁修改 `types.go` 有多痛苦,但我们很为此担心。 + + * 结构化类型在客户端中很有用。版本化的结构就可以了。 + + * 如果从 json/yaml (kubectl) 开始,则不应转换为结构化类型。使用 swagger。 + + + +* Security context + + * + + * 管理员可以限制谁可以运行特权容器或需要特定的 unix uid + + * kubelet 将能够从 apiserver 获取证书 + + * 政策提案将于下周左右出台 + + + +* 讨论用户的上游,等等进入Kubernetes,至少是可选的 +* 1.0 路线图 + + * 重点是性能,稳定性,集群升级 + + * TJ 一直在对[roadmap.md][4]进行一些编辑,但尚未发布PR +* Kubernetes UI + + * 依赖关系分解为第三方 + + * @lavalamp 是评论家 + + +[1]: http://kubernetes.io/images/nav_logo.svg +[2]: http://kubernetes.io/docs/ +[3]: https://kubernetes.io/blog/ +[4]: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/roadmap.md +[5]: https://kubernetes.io/blog/2015/04/weekly-kubernetes-community-hangout_17 "permanent link" +[6]: https://resources.blogblog.com/img/icon18_edit_allbkg.gif +[7]: https://www.blogger.com/post-edit.g?blogID=112706738355446097&postID=630924463010638300&from=pencil "Edit Post" +[8]: https://www.blogger.com/share-post.g?blogID=112706738355446097&postID=630924463010638300&target=email "Email This" +[9]: https://www.blogger.com/share-post.g?blogID=112706738355446097&postID=630924463010638300&target=blog "BlogThis!" +[10]: https://www.blogger.com/share-post.g?blogID=112706738355446097&postID=630924463010638300&target=twitter "Share to Twitter" +[11]: https://www.blogger.com/share-post.g?blogID=112706738355446097&postID=630924463010638300&target=facebook "Share to Facebook" +[12]: https://www.blogger.com/share-post.g?blogID=112706738355446097&postID=630924463010638300&target=pinterest "Share to Pinterest" +[13]: https://kubernetes.io/blog/search/label/community%20meetings +[14]: https://kubernetes.io/blog/search/label/containers +[15]: https://kubernetes.io/blog/search/label/docker +[16]: https://kubernetes.io/blog/search/label/k8s +[17]: https://kubernetes.io/blog/search/label/kubernetes +[18]: https://kubernetes.io/blog/search/label/open%20source +[19]: https://kubernetes.io/blog/2015/04/kubernetes-and-mesosphere-dcos "Newer Post" +[20]: https://kubernetes.io/blog/2015/04/introducing-kubernetes-v1beta3 "Older Post" +[21]: https://kubernetes.io/blog/feeds/630924463010638300/comments/default +[22]: https://img2.blogblog.com/img/widgets/arrow_dropdown.gif +[23]: https://img1.blogblog.com/img/icon_feed12.png +[24]: https://img1.blogblog.com/img/widgets/subscribe-netvibes.png +[25]: https://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fblog.kubernetes.io%2Ffeeds%2Fposts%2Fdefault +[26]: https://img1.blogblog.com/img/widgets/subscribe-yahoo.png +[27]: https://add.my.yahoo.com/content?url=http%3A%2F%2Fblog.kubernetes.io%2Ffeeds%2Fposts%2Fdefault +[28]: https://kubernetes.io/blog/feeds/posts/default +[29]: https://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fblog.kubernetes.io%2Ffeeds%2F630924463010638300%2Fcomments%2Fdefault +[30]: https://add.my.yahoo.com/content?url=http%3A%2F%2Fblog.kubernetes.io%2Ffeeds%2F630924463010638300%2Fcomments%2Fdefault +[31]: https://resources.blogblog.com/img/icon18_wrench_allbkg.png +[32]: //www.blogger.com/rearrange?blogID=112706738355446097&widgetType=Subscribe&widgetId=Subscribe1&action=editWidget§ionId=sidebar-right-1 "Edit" +[33]: https://twitter.com/kubernetesio +[34]: https://github.com/kubernetes/kubernetes +[35]: http://slack.k8s.io/ +[36]: http://stackoverflow.com/questions/tagged/kubernetes +[37]: http://get.k8s.io/ +[38]: //www.blogger.com/rearrange?blogID=112706738355446097&widgetType=HTML&widgetId=HTML2&action=editWidget§ionId=sidebar-right-1 "Edit" +[39]: javascript:void(0) +[40]: https://kubernetes.io/blog/2018/ +[41]: https://kubernetes.io/blog/2018/01/ +[42]: https://kubernetes.io/blog/2017/ +[43]: https://kubernetes.io/blog/2017/12/ +[44]: https://kubernetes.io/blog/2017/11/ +[45]: https://kubernetes.io/blog/2017/10/ +[46]: https://kubernetes.io/blog/2017/09/ +[47]: https://kubernetes.io/blog/2017/08/ +[48]: https://kubernetes.io/blog/2017/07/ +[49]: https://kubernetes.io/blog/2017/06/ +[50]: https://kubernetes.io/blog/2017/05/ +[51]: https://kubernetes.io/blog/2017/04/ +[52]: https://kubernetes.io/blog/2017/03/ +[53]: https://kubernetes.io/blog/2017/02/ +[54]: https://kubernetes.io/blog/2017/01/ +[55]: https://kubernetes.io/blog/2016/ +[56]: https://kubernetes.io/blog/2016/12/ +[57]: https://kubernetes.io/blog/2016/11/ +[58]: https://kubernetes.io/blog/2016/10/ +[59]: https://kubernetes.io/blog/2016/09/ +[60]: https://kubernetes.io/blog/2016/08/ +[61]: https://kubernetes.io/blog/2016/07/ +[62]: https://kubernetes.io/blog/2016/06/ +[63]: https://kubernetes.io/blog/2016/05/ +[64]: https://kubernetes.io/blog/2016/04/ +[65]: https://kubernetes.io/blog/2016/03/ +[66]: https://kubernetes.io/blog/2016/02/ +[67]: https://kubernetes.io/blog/2016/01/ +[68]: https://kubernetes.io/blog/2015/ +[69]: https://kubernetes.io/blog/2015/12/ +[70]: https://kubernetes.io/blog/2015/11/ +[71]: https://kubernetes.io/blog/2015/10/ +[72]: https://kubernetes.io/blog/2015/09/ +[73]: https://kubernetes.io/blog/2015/08/ +[74]: https://kubernetes.io/blog/2015/07/ +[75]: https://kubernetes.io/blog/2015/06/ +[76]: https://kubernetes.io/blog/2015/05/ +[77]: https://kubernetes.io/blog/2015/04/ +[78]: https://kubernetes.io/blog/2015/04/weekly-kubernetes-community-hangout_29 +[79]: https://kubernetes.io/blog/2015/04/borg-predecessor-to-kubernetes +[80]: https://kubernetes.io/blog/2015/04/kubernetes-and-mesosphere-dcos +[81]: https://kubernetes.io/blog/2015/04/weekly-kubernetes-community-hangout_17 +[82]: https://kubernetes.io/blog/2015/04/introducing-kubernetes-v1beta3 +[83]: https://kubernetes.io/blog/2015/04/kubernetes-release-0150 +[84]: https://kubernetes.io/blog/2015/04/weekly-kubernetes-community-hangout_11 +[85]: https://kubernetes.io/blog/2015/04/faster-than-speeding-latte +[86]: https://kubernetes.io/blog/2015/04/weekly-kubernetes-community-hangout +[87]: https://kubernetes.io/blog/2015/03/ +[88]: //www.blogger.com/rearrange?blogID=112706738355446097&widgetType=BlogArchive&widgetId=BlogArchive1&action=editWidget§ionId=sidebar-right-1 "Edit" +[89]: //www.blogger.com/rearrange?blogID=112706738355446097&widgetType=HTML&widgetId=HTML1&action=editWidget§ionId=sidebar-right-1 "Edit" +[90]: https://www.blogger.com +[91]: //www.blogger.com/rearrange?blogID=112706738355446097&widgetType=Attribution&widgetId=Attribution1&action=editWidget§ionId=footer-3 "Edit" + + [*[3:27 PM]: 2015-04-17T15:27:00-07:00 diff --git a/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_29.md b/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_29.md new file mode 100644 index 0000000000000..c451022671a51 --- /dev/null +++ b/content/zh/blog/_posts/2015-04-00-Weekly-Kubernetes-Community-Hangout_29.md @@ -0,0 +1,143 @@ +--- +title: " Kubernetes 社区每周聚会笔记- 2015年4月24日 " +date: 2015-04-30 +slug: weekly-kubernetes-community-hangout_29 +url: /blog/2015/04/Weekly-Kubernetes-Community-Hangout_29 +--- + + + + +每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。 + + +日程安排: + +* Flocker 和 Kubernetes 集成演示 + + +笔记: + +* flocker 和 kubernetes 集成演示 +* * Flocker Q/A + + * 迁移后文件是否仍存在于node1上? + + * Brendan: 有没有计划把它做成一本书?我们不需要 powerstrip? + + * Luke: 需要找出感兴趣的来决定我们是否想让它成为 kube 中的一个一流的持久性磁盘提供商。 + + * Brendan: 删除对 powerstrip 的需求会使其易于使用。完全去做。 + + * Tim: 将它添加到 kubernetes 应该不超过45分钟:) + + + + * Derek: 持久卷和请求相比呢? + + * Luke: 除了基于 ZFS 的新后端之外,差别不大。使工作负载真正可移植。 + + * Tim: 与基于网络的卷非常不同。有趣的是,它是唯一允许升级媒体的产品。 + + * Brendan: 请求,它如何查找重复请求?Cassandra 希望在底层复制数据。向上和向下扩缩是有效的。根据负载动态地创建存储。它的步骤不仅仅是快照——通过编程使用预分配创建副本。 + + * Tim: 帮助自动配置。 + + + + * Brian: flocker 是否需要其他组件? + + * Kai: Flocker 控制服务与主服务器位于同一位置。(dia 在博客上)。Powerstrip + Powerstrip Flocker。对在 etcd 中持久化状态非常有趣。它保存关于每个卷的元数据。 + + * Brendan: 在未来,flocker 可以是一个插件,我们将负责持久性。发布 v1.0。 + + * Brian: 有兴趣为 flocker 等服务添加通用插件。 + + * Luke: 当扩展到单个节点上的许多容器时,Zfs 会变得非常有价值。 + + + + * Alex: flocker 服务可以作为 pod 运行吗? + + * Kai: 是的,唯一的要求是 flocker 控制服务应该能够与 zfs 代理对话。需要在主机上安装 zfs 代理,并且需要访问 zfs 二进制文件。 + + * Brendan: 从理论上讲,所有 zfs 位都可以与设备一起放入容器中。 + + * Luke: 是的,仍然在处理跨容器安装问题。 + + * Tim: pmorie 正在通过它使 kubelet 在容器中工作。可能重复使用。 + + * Kai: Cinder 支持即将到来。几天之后。 +* Bob: 向 GKE 推送 kube 的过程是怎样的?需要更多的可见度。 + + diff --git a/content/zh/blog/_posts/2015-05-00-Kubernetes-On-Openstack.md b/content/zh/blog/_posts/2015-05-00-Kubernetes-On-Openstack.md new file mode 100644 index 0000000000000..0a4ac17ef5e56 --- /dev/null +++ b/content/zh/blog/_posts/2015-05-00-Kubernetes-On-Openstack.md @@ -0,0 +1,112 @@ +--- +title: " OpenStack 上的 Kubernetes " +date: 2015-05-19 +slug: kubernetes-on-openstack +url: /blog/2015/05/Kubernetes-On-Openstack +--- + + + +[![](https://3.bp.blogspot.com/-EOrCHChZJZE/VVZzq43g6CI/AAAAAAAAF-E/JUilRHk369E/s400/Untitled%2Bdrawing.jpg)](https://3.bp.blogspot.com/-EOrCHChZJZE/VVZzq43g6CI/AAAAAAAAF-E/JUilRHk369E/s1600/Untitled%2Bdrawing.jpg) + + + +今天,[OpenStack 基金会](https://www.openstack.org/foundation/)通过在其[社区应用程序目录](http://apps.openstack.org/)中包含 Kubernetes,使您更容易在 OpenStack 云上部署和管理 Docker 容器集群。 +今天在温哥华 OpenStack 峰会上的主题演讲中,OpenStack 基金会的首席运营官:Mark Collier 和 [Mirantis](https://www.mirantis.com/) 产品线经理 Craig Peters 通过利用 OpenStack 云中已经存在的计算、存储、网络和标识系统,在几秒钟内启动了 Kubernetes 集群,展示了社区应用程序目录的工作流。 + + +目录中的条目不仅包括[启动 Kubernetes 集群](http://apps.openstack.org/#tab=murano-apps&asset=Kubernetes%20Cluster)的功能,还包括部署在 Kubernetes 管理的 Docker 容器中的一系列应用程序。这些应用包括: + + + + +- +Apache web 服务器 +- +Nginx web 服务器 +- +Crate - Docker的分布式数据库 +- +GlassFish - Java EE 7 应用服务器 +- +Tomcat - 一个开源的 web 服务器和 servlet 容器 +- +InfluxDB - 一个开源的、分布式的、时间序列数据库 +- +Grafana - InfluxDB 的度量仪表板 +- +Jenkins - 一个可扩展的开放源码持续集成服务器 +- +MariaDB 数据库 +- +MySql 数据库 +- +Redis - 键-值缓存和存储 +- +PostgreSQL 数据库 +- +MongoDB NoSQL 数据库 +- +Zend 服务器 - 完整的 PHP 应用程序平台 + + +此列表将会增长,并在[此处](https://github.com/openstack/murano-apps/tree/master/Docker/Kubernetes)进行策划。您可以检查(并参与)YAML 文件,该文件告诉 Murano 如何根据[此处](https://github.com/openstack/murano-apps/blob/master/Docker/Kubernetes/KubernetesCluster/package/Classes/KubernetesCluster.yaml)定义来安装和启动 ...apps/blob/master/Docker/Kubernetes/KubernetesCluster/package/Classes/KubernetesCluster.yaml)安装和启动 Kubernetes 集群。 + + +[Kubernetes 开源项目](https://github.com/GoogleCloudPlatform/kubernetes)继续受到社区的欢迎,并且势头越来越好,GitHub 上有超过 11000 个提交和 7648 颗星。从 Red Hat 和 Intel 到 CoreOS 和 Box.net,它已经代表了从企业 IT 到前沿创业企业的一系列客户。我们鼓励您尝试一下,给我们您的反馈,并参与到我们不断增长的社区中来。 + + + + +- Martin Buhr, Kubernetes 开源项目产品经理 + diff --git a/content/zh/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout.md b/content/zh/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout.md new file mode 100644 index 0000000000000..8f60d7916bd16 --- /dev/null +++ b/content/zh/blog/_posts/2015-05-00-Weekly-Kubernetes-Community-Hangout.md @@ -0,0 +1,121 @@ +--- +title: " Kubernetes 社区每周聚会笔记- 2015年5月1日 " +date: 2015-05-11 +slug: weekly-kubernetes-community-hangout +url: /blog/2015/05/Weekly-Kubernetes-Community-Hangout +--- + + + + +每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。 + + + +* 简单的滚动更新 - Brendan + + * 滚动更新 = RCs和Pods很好的例子。 + + * ...pause… (Brendan 需要 Kelsey 的演示恢复技巧) + + * 滚动更新具有恢复功能:取消更新并重新启动,更新从停止的地方继续。 + + * 新控制器获取旧控制器的名称,因此外观是纯粹的更新。 + + * 还可以在 update 中命名版本(最后不会重命名)。 + + + +* Rocket 演示 - CoreOS 的伙计们 + + * Rocket 和 docker 之间的主要区别: Rocket 是无守护进程和以 pod 为中心。。 + + * Rocket 具有原生的 AppContainer 格式,但也支持 docker 镜像格式。 + + * 可以在同一个 pod 中运行 AppContainer 和 docker 容器。 + + * 变更接近于合并。 + + + +* 演示 service accounts 和 secrets 被添加到 pod - Jordan + + * 问题:很难获得与API通信的令牌。 + + * 新的API对象:"ServiceAccount" + + * ServiceAccount 是命名空间,控制器确保命名空间中至少存在一个个默认 service account。 + + * 键入 "ServiceAccountToken",控制器确保至少有一个默认令牌。 + + * 演示 + + * * 可以使用 ServiceAccountToken 创建新的 service account。控制器将为它创建令牌。 + + * 可以创建一个带有 service account 的 pod, pod 将在 /var/run/secrets/kubernets.io/… + + + +* Kubelet 在容器中运行 - Paul + + * Kubelet 成功地运行了带有 secret 的 pod。 + diff --git a/content/zh/blog/_posts/2015-06-00-Slides-Cluster-Management-With.md b/content/zh/blog/_posts/2015-06-00-Slides-Cluster-Management-With.md new file mode 100644 index 0000000000000..8e1c001d65373 --- /dev/null +++ b/content/zh/blog/_posts/2015-06-00-Slides-Cluster-Management-With.md @@ -0,0 +1,25 @@ +--- +title: "幻灯片:Kubernetes 集群管理,爱丁堡大学演讲" +date: 2015-06-26 +slug: slides-cluster-management-with +url: /blog/2015/06/Slides-Cluster-Management-With +--- + + + + + +2015年6月5日星期五,我在爱丁堡大学给普通听众做了一个演讲,题目是[使用 Kubernetes 进行集群管理](https://docs.google.com/presentation/d/1H4ywDb4vAJeg8KEjpYfhNqFSig0Q8e_X5I36kM9S6q0/pub?start=false&loop=false&delayms=3000)。这次演讲包括一个带有 Kibana 前端 UI 的音乐存储系统的例子,以及一个基于 Elasticsearch 的后端,该后端有助于生成具体的概念,如 pods、复制控制器和服务。 + +[Kubernetes 集群管理](https://docs.google.com/presentation/d/1H4ywDb4vAJeg8KEjpYfhNqFSig0Q8e_X5I36kM9S6q0/pub?start=false&loop=false&delayms=3000)。 diff --git a/content/zh/blog/_posts/2015-07-00-Announcing-First-Kubernetes-Enterprise.md b/content/zh/blog/_posts/2015-07-00-Announcing-First-Kubernetes-Enterprise.md new file mode 100644 index 0000000000000..d71f6bcc70047 --- /dev/null +++ b/content/zh/blog/_posts/2015-07-00-Announcing-First-Kubernetes-Enterprise.md @@ -0,0 +1,24 @@ +--- +title: "宣布首个Kubernetes企业培训课程 " +date: 2015-07-08 +slug: announcing-first-kubernetes-enterprise +url: /blog/2015/07/Announcing-First-Kubernetes-Enterprise +--- + + + +在谷歌,我们依赖 Linux 容器应用程序去运行我们的核心基础架构。所有服务,从搜索引擎到Gmail服务,都运行在容器中。事实上,我们非常喜欢容器,甚至我们的谷歌云计算引擎虚拟机也运行在容器上!由于容器对于我们的业务至关重要,我们已经与社区合作开发许多基本的容器技术(从 cgroups 到 Docker 的 LibContainer),甚至决定去构建谷歌的下一代开源容器调度技术,Kubernetes。 + + +在 Kubernetes 项目进行一年后,在 OSCON 上发布 V1 版本的前夕,我们很高兴的宣布Kubernetes 的主要贡献者 Mesosphere 组织了有史以来第一次正规的以企业为中心的 Kubernetes 培训会议。首届会议将于 6 月 20 日在波特兰的 OSCON 举办,由来自 Mesosphere 的 Zed Shaw 和 Michael Hausenblas 演讲。[Pre-registration](https://mesosphere.com/training/kubernetes/) 对于优先注册者是免费的,但名额有限,立刻行动吧! + + +这个为期一天的课程将包涵使用 Kubernetes 构建和部署容器化应用程序的基础知识。它将通过完整的流程引导与参会者创建一个 Kubernetes 的应用程序体系结构,创建和配置 Docker 镜像,并把它们部署到 Kubernetes 集群上。用户还将了解在我们的谷歌容器引擎和 Mesosphere 的数据中心操作系统上部署 Kubernetes 应用程序和服务的基础知识。 + + +即将推出的 Kubernetes bootcamp 将是学习如何应用 Kubernetes 解决长期部署和应用程序管理问题的一个好途径。相对于我们所预期的,来自于广泛社区的众多培训项目而言,这只是其中一个。 diff --git a/content/zh/blog/_posts/2015-12-00-Managing-Kubernetes-Pods-Services-And-Replication-Controllers-With-Puppet.md b/content/zh/blog/_posts/2015-12-00-Managing-Kubernetes-Pods-Services-And-Replication-Controllers-With-Puppet.md new file mode 100644 index 0000000000000..5faf8381489ea --- /dev/null +++ b/content/zh/blog/_posts/2015-12-00-Managing-Kubernetes-Pods-Services-And-Replication-Controllers-With-Puppet.md @@ -0,0 +1,164 @@ +--- +title: " 使用 Puppet 管理 Kubernetes Pods,Services 和 Replication Controllers " +date: 2015-12-17 +slug: managing-kubernetes-pods-services-and-replication-controllers-with-puppet +url: /blog/2015/12/Managing-Kubernetes-Pods-Services-And-Replication-Controllers-With-Puppet +--- + + + + + +_今天的嘉宾帖子是由 IT 自动化领域的领导者 Puppet Labs 的高级软件工程师 Gareth Rushgrove 撰写的。Gareth告诉我们一个新的 Puppet 模块,它帮助管理 Kubernetes 中的资源。_ + +熟悉[Puppet]的人(https://github.com/puppetlabs/puppet)可能使用它来管理主机上的文件、包和用户。但是Puppet首先是一个配置管理工具,配置管理是一个比管理主机级资源更广泛的规程。配置管理的一个很好的定义是它旨在解决四个相关的问题:标识、控制、状态核算和验证审计。这些问题存在于任何复杂系统的操作中,并且有了新的[Puppet Kubernetes module](https://forge.puppetlabs.com/garethr/kubernetes),我们开始研究如何为 Kubernetes 解决这些问题。 + + + +### Puppet Kubernetes 模块 + +Puppet kubernetes 模块目前假设您已经有一个 kubernetes 集群 [启动并运行]](http://kubernetes.io/gettingstarted/)。它的重点是管理 Kubernetes中的资源,如 Pods、Replication Controllers 和 Services,而不是(现在)管理底层的 kubelet 或 etcd services。下面是描述 Puppet’s DSL 中一个 Pod 的简短代码片段。 + + + +``` +kubernetes_pod { 'sample-pod': + ensure => present, + metadata => { + namespace => 'default', + }, + spec => { + containers => [{ + name => 'container-name', + image => 'nginx', + }] + }, +} +``` + + +如果您熟悉 YAML 文件格式,您可能会立即识别该结构。 该接口故意采取相同的格式以帮助在不同格式之间进行转换 — 事实上,为此提供支持的代码是从Kubernetes API Swagger自动生成的。 运行上面的代码,假设我们将其保存为 pod.pp,就像下面这样简单: + + +``` +puppet apply pod.pp +``` + + + +身份验证使用标准的 kubectl 配置文件。您可以在模块的自述文件中找到完整的[README](https://github.com/garethr/garethr-kubernetes/blob/master/README.md)。 + +Kubernetes 有很多资源,来自 Pods、 Services、 Replication Controllers 和 Service Accounts。您可以在[Puppet 中的 kubernetes 留言簿示例](https://puppetlabs.com/blog/kubernetes-guestbook-example-puppet)文章中看到管理这些资源的模块示例。这演示了如何将规范的 hello-world 示例转换为使用 Puppet代码。 + + + +然而,使用 Puppet 的一个主要优点是,您可以创建自己的更高级别和更特定于业务的接口,以连接 kubernetes 管理的应用程序。例如,对于留言簿,可以创建如下内容: + +``` +guestbook { 'myguestbook': + redis_slave_replicas => 2, + frontend_replicas => 3, + redis_master_image => 'redis', + redis_slave_image => 'gcr.io/google_samples/gb-redisslave:v1', + frontend_image => 'gcr.io/google_samples/gb-frontend:v3', +} +``` + + + +您可以在Puppet博客文章[在 Puppet 中为 Kubernetes 构建自己的抽象](https://puppetlabs.com/blog/building-your-own-abstractions-kubernetes-puppet)中阅读更多关于使用 Puppet 定义的类型的信息,并看到更多的代码示例。 + + +### 结论 + +使用 Puppet 而不仅仅是使用标准的 YAML 文件和 kubectl 的优点是: + + + +- 能够创建自己的抽象,以减少重复和设计更高级别的用户界面,如上面的留言簿示例。 +- 使用 Puppet 的开发工具验证代码和编写单元测试。 +- 与 Puppet Server 等其他工具配合,以确保代码中的模型与集群的状态匹配,并与 PuppetDB 配合工作,以存储报告和跟踪更改。 +- 能够针对 Kubernetes API 重复运行相同的代码,以检测任何更改或修正配置。 + + + +值得注意的是,大多数大型组织都将拥有非常异构的环境,运行各种各样的软件和操作系统。拥有统一这些离散系统的单一工具链可以使采用 Kubernetes 等新技术变得更加容易。 + + + +可以肯定地说,Kubernetes提供了一组优秀的组件来构建云原生系统。使用 Puppet,您可以解决在生产中运行任何复杂系统所带来的一些操作和配置管理问题。[告诉我们](mailto:gareth@puppetlabs.com)如果您试用了该模块,您会有什么想法,以及您希望在将来看到哪些支持。 + + +Gareth Rushgrove,Puppet Labs 高级软件工程师 + diff --git a/content/zh/blog/_posts/2016-01-00-Simple-Leader-Election-With-Kubernetes.md b/content/zh/blog/_posts/2016-01-00-Simple-Leader-Election-With-Kubernetes.md new file mode 100644 index 0000000000000..bcea1c026e4cc --- /dev/null +++ b/content/zh/blog/_posts/2016-01-00-Simple-Leader-Election-With-Kubernetes.md @@ -0,0 +1,303 @@ + + +title: "Kubernetes 和 Docker 简单的 leader election" +date: 2016-01-11 +slug: simple-leader-election-with-kubernetes +url: /blog/2016/01/Simple-Leader-Election-With-Kubernetes + + + +Kubernetes 简化了集群上运行的服务的部署和操作管理。但是,它也简化了这些服务的发展。在本文中,我们将看到如何使用 Kubernetes 在分布式应用程序中轻松地执行 leader election。分布式应用程序通常为了可靠性和可伸缩性而复制服务的任务,但通常需要指定其中一个副本作为负责所有副本之间协调的负责人。 + + + +通常在 leader election 中,会确定一组成为领导者的候选人。这些候选人都竞相宣布自己为领袖。其中一位候选人获胜并成为领袖。一旦选举获胜,领导者就会不断地“信号”以表示他们作为领导者的地位,其他候选人也会定期地做出新的尝试来成为领导者。这样可以确保在当前领导因某种原因失败时,快速确定新领导。 + + + +实现 leader election 通常需要部署 ZooKeeper、etcd 或 Consul 等软件并将其用于协商一致,或者也可以自己实现协商一致算法。我们将在下面看到,Kubernetes 使在应用程序中使用 leader election 的过程大大简化。 + +####在 Kubernetes 实施领导人选举 + + + +Leader election 的首要条件是确定候选人的人选。Kubernetes 已经使用 _Endpoints_ 来表示组成服务的一组复制 pod,因此我们将重用这个相同的对象。(旁白:您可能认为我们会使用 _ReplicationControllers_,但它们是绑定到特定的二进制文件,而且通常您希望只有一个领导者,即使您正在执行滚动更新) + +要执行 leader election,我们使用所有 Kubernetes api 对象的两个属性: + + + +* ResourceVersions - 每个 API 对象都有一个惟一的 ResourceVersion,您可以使用这些版本对 Kubernetes 对象执行比较和交换 +* Annotations - 每个 API 对象都可以用客户端使用的任意键/值对进行注释。 + +给定这些原语,使用 master election 的代码相对简单,您可以在这里找到[here][1]。我们自己来做吧。 + + + +``` +$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example +``` + +这将创建一个包含3个副本的 leader election 集合: + +``` +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +leader-elector-inmr1 1/1 Running 0 13s +leader-elector-qkq00 1/1 Running 0 13s +leader-elector-sgwcq 1/1 Running 0 13s +``` + + + +要查看哪个pod被选为领导,您可以访问其中一个 pod 的日志,用您自己的一个 pod 的名称替换 + +``` +${pod_name}, (e.g. leader-elector-inmr1 from the above) + +$ kubectl logs -f ${name} +leader is (leader-pod-name) +``` +…或者,可以直接检查 endpoints 对象: + + + +_'example' 是上面 kubectl run … 命令_中候选集的名称 +``` +$ kubectl get endpoints example -o yaml +``` +现在,要验证 leader election 是否实际有效,请在另一个终端运行: +``` +$ kubectl delete pods (leader-pod-name) +``` + + + +这将删除现有领导。由于 pod 集由 replication controller 管理,因此新的 pod 将替换已删除的pod,确保复制集的大小仍为3。通过 leader election,这三个pod中的一个被选为新的领导者,您应该会看到领导者故障转移到另一个pod。因为 Kubernetes 的吊舱在终止前有一个 _grace period_,这可能需要30-40秒。 + +Leader-election container 提供了一个简单的 web 服务器,可以服务于任何地址(e.g. http://localhost:4040)。您可以通过删除现有的 leader election 组并创建一个新的 leader elector 组来测试这一点,在该组中,您还可以向 leader elector 映像传递--http=(host):(port) 规范。这将导致集合中的每个成员通过 webhook 提供有关领导者的信息。 + + + +``` +# delete the old leader elector group +$ kubectl delete rc leader-elector + +# create the new group, note the --http=localhost:4040 flag +$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example --http=0.0.0.0:4040 + +# create a proxy to your Kubernetes api server +$ kubectl proxy +``` + + + +然后您可以访问: + + + + +http://localhost:8001/api/v1/proxy/namespaces/default/pods/(leader-pod-name):4040/ + + + + +你会看到: + +``` +{"name":"(name-of-leader-here)"} +``` +#### 有副手的 leader election + + + +好吧,那太好了,你可以通过 HTTP 进行leader election 并找到 leader,但是你如何从自己的应用程序中使用它呢?这就是 sidecar 的由来。Kubernetes 中,Pods 由一个或多个容器组成。通常情况下,这意味着您将 sidecar containers 添加到主应用程序中以组成 pod。(关于这个主题的更详细的处理,请参阅我之前的博客文章)。 +Leader-election container 可以作为一个 sidecar,您可以从自己的应用程序中使用。Pod 中任何对当前 master 感兴趣的容器都可以简单地访问http://localhost:4040,它们将返回一个包含当前 master 名称的简单 json 对象。由于 pod中 的所有容器共享相同的网络命名空间,因此不需要服务发现! + + + +例如,这里有一个简单的 Node.js 应用程序,它连接到 leader election sidecar 并打印出它当前是否是 master。默认情况下,leader election sidecar 将其标识符设置为 `hostname`。 + +``` +var http = require('http'); +// This will hold info about the current master +var master = {}; + + // The web handler for our nodejs application + var handleRequest = function(request, response) { + response.writeHead(200); + response.end("Master is " + master.name); + }; + + // A callback that is used for our outgoing client requests to the sidecar + var cb = function(response) { + var data = ''; + response.on('data', function(piece) { data = data + piece; }); + response.on('end', function() { master = JSON.parse(data); }); + }; + + // Make an async request to the sidecar at http://localhost:4040 + var updateMaster = function() { + var req = http.get({host: 'localhost', path: '/', port: 4040}, cb); + req.on('error', function(e) { console.log('problem with request: ' + e.message); }); + req.end(); + }; + + / / Set up regular updates + updateMaster(); + setInterval(updateMaster, 5000); + + // set up the web server + var www = http.createServer(handleRequest); + www.listen(8080); + ``` + 当然,您可以从任何支持 HTTP 和 JSON 的语言中使用这个 sidecar。 + + + +#### 结论 + + + 希望我已经向您展示了使用 Kubernetes 为您的分布式应用程序构建 leader election 是多么容易。在以后的部分中,我们将向您展示 Kubernetes 如何使构建分布式系统变得更加容易。同时,转到[Google Container Engine][2]或[kubernetes.io][3]开始使用Kubernetes。 + + [1]: https://github.com/kubernetes/contrib/pull/353 + [2]: https://cloud.google.com/container-engine/ + [3]: http://kubernetes.io/ \ No newline at end of file diff --git a/content/zh/blog/_posts/2016-01-00-Why-Kubernetes-Doesnt-Use-Libnetwork.md b/content/zh/blog/_posts/2016-01-00-Why-Kubernetes-Doesnt-Use-Libnetwork.md new file mode 100644 index 0000000000000..424a68d0777ad --- /dev/null +++ b/content/zh/blog/_posts/2016-01-00-Why-Kubernetes-Doesnt-Use-Libnetwork.md @@ -0,0 +1,79 @@ +--- +title: " 为什么 Kubernetes 不用 libnetwork " +date: 2016-01-14 +slug: why-kubernetes-doesnt-use-libnetwork +url: /blog/2016/01/Why-Kubernetes-Doesnt-Use-Libnetwork +--- + + + + + +在 1.0 版本发布之前,Kubernetes 已经有了一个非常基础的网络插件形式-大约在引入 Docker’s [libnetwork](https://github.com/docker/libnetwork) 和 Container Network Model ([CNM](https://github.com/docker/libnetwork/blob/master/docs/design.md)) 的时候。与 libnetwork 不同,Kubernetes 插件系统仍然保留它的 'alpha' 名称。现在 Docker 的网络插件支持已经发布并得到支持,我们发现一个明显的问题是 Kubernetes 尚未采用它。毕竟,供应商几乎肯定会为 Docker 编写插件-我们最好还是用相同的驱动程序,对吧? + + + +在进一步说明之前,重要的是记住 Kubernetes 是一个支持多种容器运行时的系统, Docker 只是其中之一。配置网络只是每一个运行时的一个方面,所以当人们问起“ Kubernetes 会支持CNM吗?”,他们真正的意思是“ Kubernetes 会支持 Docker 运行时的 CNM 驱动吗?”如果我们能够跨运行时实现通用的网络支持会很棒,但这不是一个明确的目标。 + + + +实际上, Kubernetes 还没有为 Docker 运行时采用 CNM/libnetwork 。事实上,我们一直在研究 CoreOS 提出的替代 Container Network Interface ([CNI](https://github.com/appc/cni/blob/master/SPEC.md)) 模型以及 App Container ([appc](https://github.com/appc)) 规范的一部分。为什么我们要这么做?有很多技术和非技术的原因。 + + + +首先,Docker 的网络驱动程序设计中存在一些基本假设,这些假设会给我们带来问题。 + + + +Docker 有一个“本地”和“全局”驱动程序的概念。本地驱动程序(例如 "bridge" )以机器为中心,不进行任何跨节点协调。全局驱动程序(例如 "overlay" )依赖于 [libkv](https://github.com/docker/libkv) (一个键值存储抽象库)来协调跨机器。这个键值存储是另一个插件接口,并且是非常低级的(键和值,没有其他含义)。 要在 Kubernetes 集群中运行类似 Docker's overlay 驱动程序,我们要么需要集群管理员来运行 [consul](https://github.com/hashicorp/consul), [etcd](https://github.com/coreos/etcd) 或 [zookeeper](https://zookeeper.apache.org/) 的整个不同实例 (see [multi-host networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/)) 否则我们必须提供我们自己的 libkv 实现,那被 Kubernetes 支持。 + + + +后者听起来很有吸引力,并且我们尝试实现它,但 libkv 接口是非常低级的,并且架构在内部定义为 Docker 。我们必须直接暴露我们的底层键值存储,或者提供键值语义(在我们的结构化API之上,它本身是在键值系统上实现的)。对于性能,可伸缩性和安全性原因,这些都不是很有吸引力。最终结果是,当使用 Docker 网络的目标是简化事情时,整个系统将显得更加复杂。 + + + +对于愿意并且能够运行必需的基础架构以满足 Docker 全局驱动程序并自己配置 Docker 的用户, Docker 网络应该“正常工作。” Kubernetes 不会妨碍这样的设置,无论项目的方向如何,该选项都应该可用。但是对于默认安装,实际的结论是这对用户来说是一个不应有的负担,因此我们不能使用 Docker 的全局驱动程序(包括 "overlay" ),这消除了使用 Docker 插件的很多价值。 + + + +Docker 的网络模型做出了许多对 Kubernetes 无效的假设。在 docker 1.8 和 1.9 版本中,它包含一个从根本上有缺陷的“发现”实现,导致容器中的 `/etc/hosts` 文件损坏 ([docker #17190](https://github.com/docker/docker/issues/17190)) - 并且这不容易被关闭。在 1.10 版本中,Docker 计划 [捆绑一个新的DNS服务器](https://github.com/docker/docker/issues/17195),目前还不清楚是否可以关闭它。容器级命名不是 Kubernetes 的正确抽象 - 我们已经有了自己的服务命名,发现和绑定概念,并且我们已经有了自己的 DNS 模式和服务器(基于完善的 [SkyDNS](https://github.com/skynetservices/skydns) )。捆绑的解决方案不足以满足我们的需求,但不能禁用。 + + + +与本地/全局拆分正交, Docker 具有进程内和进程外( "remote" )插件。我们调查了是否可以绕过 libnetwork (从而跳过上面的问题)并直接驱动 Docker remote 插件。不幸的是,这意味着我们无法使用任何 Docker 进程中的插件,特别是 "bridge" 和 "overlay",这再次消除了 libnetwork 的大部分功能。 + + + +另一方面, CNI 在哲学上与 Kubernetes 更加一致。它比 CNM 简单得多,不需要守护进程,并且至少是合理的跨平台( CoreOS 的 [rkt](https://coreos.com/rkt/docs/) 容器运行时支持它)。跨平台意味着有机会启用跨运行时(例如 Docker , Rocket , Hyper )运行相同的网络配置。 它遵循 UNIX 的理念,即做好一件事。 + + + +此外,包装 CNI 插件并生成更加个性化的 CNI 插件是微不足道的 - 它可以通过简单的 shell 脚本完成。 CNM 在这方面要复杂得多。这使得 CNI 对于快速开发和迭代是有吸引力的选择。早期的原型已经证明,可以将 kubelet 中几乎 100% 的当前硬编码网络逻辑弹出到插件中。 + + + +我们调查了为 Docker [编写 "bridge" CNM驱动程序](https://groups.google.com/forum/#!topic/kubernetes-sig-network/5MWRPxsURUw) 并运行 CNI 驱动程序。事实证明这非常复杂。首先, CNM 和 CNI 模型非常不同,因此没有一种“方法”协调一致。 我们仍然有上面讨论的全球与本地和键值问题。假设这个驱动程序会声明自己是本地的,我们必须从 Kubernetes 获取有关逻辑网络的信息。 + + + +不幸的是, Docker 驱动程序很难映射到像 Kubernetes 这样的其他控制平面。具体来说,驱动程序不会被告知连接容器的网络名称 - 只是 Docker 内部分配的 ID 。这使得驱动程序很难映射回另一个系统中存在的任何网络概念。 + + + +这个问题和其他问题已由网络供应商提出给 Docker 开发人员,并且通常关闭为“按预期工作”,([libnetwork #139](https://github.com/docker/libnetwork/issues/139), [libnetwork #486](https://github.com/docker/libnetwork/issues/486), [libnetwork #514](https://github.com/docker/libnetwork/pull/514), [libnetwork #865](https://github.com/docker/libnetwork/issues/865), [docker #18864](https://github.com/docker/docker/issues/18864)),即使它们使非 Docker 第三方系统更难以与之集成。在整个调查过程中, Docker 明确表示他们对偏离当前路线或委托控制的想法不太欢迎。这对我们来说非常令人担忧,因为 Kubernetes 补充了 Docker 并增加了很多功能,但它存在于 Docker 之外。 + + + +出于所有这些原因,我们选择投资 CNI 作为 Kubernetes 插件模型。这会有一些不幸的副作用。它们中的大多数都相对较小(例如, `docker inspect` 不会显示 IP 地址),但有些是重要的。特别是,由 `docker run` 启动的容器可能无法与 Kubernetes 启动的容器通信,如果网络集成商想要与 Kubernetes 完全集成,则必须提供 CNI 驱动程序。另一方面, Kubernetes 将变得更简单,更灵活,早期引入的许多丑陋的(例如配置 Docker 使用我们的网桥)将会消失。 + + + +当我们沿着这条道路前进时,我们肯定会保持眼睛和耳朵的开放,以便更好地整合和简化。如果您对我们如何做到这一点有所想法,我们真的希望听到它们 - 在 [slack](http://slack.k8s.io/) 或者 [network SIG mailing-list](https://groups.google.com/forum/#!forum/kubernetes-sig-network) 找到我们。 + +Tim Hockin, Software Engineer, Google diff --git a/content/zh/blog/_posts/2016-02-00-Kubecon-Eu-2016-Kubernetes-Community-In.md b/content/zh/blog/_posts/2016-02-00-Kubecon-Eu-2016-Kubernetes-Community-In.md new file mode 100644 index 0000000000000..d4ee22a2b1eb5 --- /dev/null +++ b/content/zh/blog/_posts/2016-02-00-Kubecon-Eu-2016-Kubernetes-Community-In.md @@ -0,0 +1,84 @@ +--- +title: " KubeCon EU 2016:伦敦 Kubernetes 社区 " +date: 2016-02-24 +slug: kubecon-eu-2016-kubernetes-community-in +url: /blog/2016/02/Kubecon-Eu-2016-Kubernetes-Community-In +--- + + + + +KubeCon EU 2016 是首届[欧洲 Kubernetes](http://kubernetes.io/) 社区会议,紧随 2015 年 11 月召开的北美会议。KubeCon 致力于为 [Kubernetes](http://kubernetes.io/) 爱好者、产品用户和周围的生态系统提供教育和社区参与。 + + +快来加入我们在伦敦,与 Kubernetes 社区的数百人一起出去,体验各种深入的技术专家讲座和用例。 + + +不要错过这些优质的演讲: + + + +* “Kubernetes 硬件黑客:通过旋钮、推杆和滑块探索 Kubernetes API” 演讲者 Ian Lewis 和 Brian Dorsey,谷歌开发布道师* [http://sched.co/6Bl3](http://sched.co/6Bl3) + +* “rktnetes: 容器运行时和 Kubernetes 的新功能” 演讲者 Jonathan Boulle, CoreOS 的主程 -* [http://sched.co/6BY7](http://sched.co/6BY7) + +* “Kubernetes 文档:贡献、修复问题、收集奖金” 作者:John Mulhausen,首席技术作家,谷歌 -* [http://sched.co/6BUP](http://sched.co/6BUP)  +* “[OpenStack 在 Kubernetes 的世界中扮演什么角色?](https://kubeconeurope2016.sched.org/event/6BYC/what-is-openstacks-role-in-a-kubernetes-world?iframe=yes&w=i:0;&sidebar=yes&bg=no#?iframe=yes&w=i:100;&sidebar=yes&bg=no)” 作者:Thierry carez, OpenStack 基金会工程总监 -* http://sched.co/6BYC +* “容器调度的实用指南” 作者:Mandy Waite,开发者倡导者,谷歌 -* [http://sched.co/6BZa](http://sched.co/6BZa) + +* “[《纽约时报》编辑部正在制作 Kubernetes](https://kubeconeurope2016.sched.org/event/67f2/kubernetes-in-production-in-the-new-york-times-newsroom?iframe=yes&w=i:0;&sidebar=yes&bg=no#?iframe=yes&w=i:100;&sidebar=yes&bg=no)” Eric Lewis,《纽约时报》网站开发人员 -* [http://sched.co/67f2](http://sched.co/67f2) +* “[使用 NGINX 为 Kubernetes 创建一个高级负载均衡解决方案](https://kubeconeurope2016.sched.org/event/6Bc9/creating-an-advanced-load-balancing-solution-for-kubernetes-with-nginx?iframe=yes&w=i:0;&sidebar=yes&bg=no#?iframe=yes&w=i:100;&sidebar=yes&bg=no)” 作者:Andrew Hutchings, NGINX 技术产品经理 -* http://sched.co/6Bc9 +* 还有更多 http://kubeconeurope2016.sched.org/ + + +[在这里](https://ti.to/kubecon/kubecon-eu-2016)获取您的 KubeCon EU 门票。 + + +会场地址:CodeNode * 英国伦敦南广场 10 号 +酒店住宿:[酒店](https://skillsmatter.com/contact-us) +网站:[kubecon.io] (https://www.kubecon.io/) +推特:[@KubeConio] (https://twitter.com/kubeconio) +谷歌是 KubeCon EU 2016 的钻石赞助商。下个月 3 月 10 - 11 号来伦敦,参观 13 号展位,了解 Kubernetes,Google Container Engine(GKE),Google Cloud Platform 的所有信息! + + + +_KubeCon 是由 KubeAcademy、LLC 组织的,这是一个由社区驱动的开发者团体,专注于开发人员的教育和 kubernet.com 的推广 +-* Sarah Novotny, 谷歌的 Kubernetes 社区经理 + diff --git a/content/zh/blog/_posts/2016-02-00-Kubernetes-Community-Meeting-Notes.md b/content/zh/blog/_posts/2016-02-00-Kubernetes-Community-Meeting-Notes.md new file mode 100644 index 0000000000000..5d1037f747226 --- /dev/null +++ b/content/zh/blog/_posts/2016-02-00-Kubernetes-Community-Meeting-Notes.md @@ -0,0 +1,117 @@ +--- +title: " Kubernetes 社区会议记录 - 20160204 " +date: 2016-02-09 +slug: kubernetes-community-meeting-notes +url: /blog/2016/02/Kubernetes-Community-Meeting-Notes +--- + + +#### 2月4日 - rkt演示(祝贺 1.0 版本, CoreOS!), eBay 将 k8s 放在 Openstack 上并认为 Openstack 在 k8s, SIG 和片状测试激增方面取得了进展。 + + +Kubernetes 贡献社区在每周四 10:00 PT 开会,通过视频会议讨论项目状态。以下是最近一次会议的笔记。 + + +* 书记员:Rob Hirschfeld +* 演示视频(20分钟):CoreOS rkt + Kubernetes[Shaya Potter] + * 期待在未来几个月内看到与rkt和k8s的整合(“rkt-netes”)。 还没有集成到 v1.2版本中。 + * Shaya 做了一个演示(8分钟的会议视频参考) + * rkt的CLI显示了旋转容器 + * [注意:音频在点数上是乱码] + * 关于 k8s&rkt 整合的讨论 + * 下周 rkt 社区同步:https://groups.google.com/forum/#!topic/rkt-dev/FlwZVIEJGbY + * Dawn Chen: + * 将 rkt 与 kubernetes 集成的其余问题:1)cadivsor 2) DNS 3)与日志记录相关的错误 + * 但是需要在 e2e 测试套件上做更多的工作 + +* 用例(10分钟):在 OpenStack 上的 eBay k8s 和 k8s 上的 OpenStack [Ashwin Raveendran] + * eBay 目前正在 OpenStack 上运行 Kubernetes + * eBay 的目标是管理带有 k8s 的 OpenStack 控制平面。目标是实现升级。 + * OpenStack Kolla 为控制平面创建容器。使用 Ansible+Docker 来管理容器。 + * 致力于 k8s 控制计划管理 - Saltstack 被证明是他们想运营的规模的管理挑战。寻找 k8s 控制平面的自动化管理。 + +* SIG 报告 +* 测试更新 [Jeff, Joe, 和 Erick] + * 努力使有助于 K8s 的工作流程更容易理解 + * [pull/19714][1]有 bot 流程图来帮助用户理解 + * 需要一种一致的方法来运行测试 w/hacking 配置脚本(你现在必须伪造一个 Jenkins 进程) + * 想要创建必要的基础设施,使测试设置不那么薄弱 + * 想要将测试开始(单次或完整)与 Jenkins分离 + * 目标是指出你有一个可以指向任何集群的脚本 + * 演示包括 Google 内部视图 - 努力尝试获取外部视图。 + * 希望能够收集测试运行结果 + * Bob Wise 不赞同在 v1.3 版本进行测试方面的基础设施建设。 + * 关于测试实践的长期讨论… + * 我们希望在多个平台上进行测试的共识。 + * 为测试报告提供一个全面转储会很有帮助 + * 可以使用"phone-home"收集异常 + + + +* 1.2发布观察 +* CoC [Sarah] +* GSoC [Sarah] + + +要参与 Kubernetes 社区,请考虑加入我们的[Slack 频道][2],查看 GitHub上的 [Kubernetes 项目][3],或加入[Kubernetes-dev Google 小组][4]。如果你真的很兴奋,你可以完成上述所有工作并加入我们的下一次社区对话-2016年2月11日。请将您自己或您想要了解的主题添加到[议程][5]并通过加入[此组][6]来获取日历邀请。 + + "https://youtu.be/IScpP8Cj0hw?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ" + + +[1]: https://github.com/kubernetes/kubernetes/pull/19714 +[2]: http://slack.k8s.io/ +[3]: https://github.com/kubernetes/ +[4]: https://groups.google.com/forum/#!forum/kubernetes-dev +[5]: https://docs.google.com/document/d/1VQDIAB0OqiSjIHI8AWMvSdceWhnz56jNpZrLs6o7NJY/edit# +[6]: https://groups.google.com/forum/#!forum/kubernetes-community-video-chat diff --git a/content/zh/blog/_posts/2016-04-Kubernetes-Network-Policy-APIs.md b/content/zh/blog/_posts/2016-04-Kubernetes-Network-Policy-APIs.md index 072ec679f3b41..e9b6e2f0848be 100644 --- a/content/zh/blog/_posts/2016-04-Kubernetes-Network-Policy-APIs.md +++ b/content/zh/blog/_posts/2016-04-Kubernetes-Network-Policy-APIs.md @@ -1,16 +1,16 @@ - - --- -title: "SIG-Networking: Kubernetes Network Policy APIs Coming in 1.3 " + + diff --git a/content/zh/blog/_posts/2016-04-Kubernetes-On-Aws_15.md b/content/zh/blog/_posts/2016-04-Kubernetes-On-Aws_15.md index c5de9e6a1285e..a12060b915706 100644 --- a/content/zh/blog/_posts/2016-04-Kubernetes-On-Aws_15.md +++ b/content/zh/blog/_posts/2016-04-Kubernetes-On-Aws_15.md @@ -1,16 +1,16 @@ - - --- -title: " 如何在AWS上部署安全,可审计,可复现的k8s集群 " + + + + +编者按:今天的客座文章来自 Citrix Systems 的产品管理总监 Mikko Disini,他分享了他们在 Kubernetes 集成上的合作经验。 _ + + +技术合作就像体育运动。如果你能像一个团队一样合作,你就能在最后关头取得胜利。这就是我们对谷歌云平台团队的经验。 + + +最近,我们与 Google 云平台(GCP)联系,代表 Citrix 客户以及更广泛的企业市场,希望就工作负载的迁移进行协作。此迁移需要将 [NetScaler Docker 负载均衡器]https://www.citrix.com/blogs/2016/06/20/the-best-docker-load-balancer-at-dockercon-in-seattle-this-week/) CPX 包含到 Kubernetes 节点中,并解决将流量引入 CPX 代理的任何问题。 + + + +**为什么是 NetScaler 和 Kubernetes** + + + +1. Citrix 的客户希望他们开始使用 Kubernetes 部署他们的容器和微服务体系结构时,能够像当初迁移到云计算时一样,享有 NetScaler 所提供的第 4 层到第 7 层能力  +2. Kubernetes 提供了一套经过验证的基础设施,可用来运行容器和虚拟机,并自动交付工作负载; +3. NetScaler CPX 提供第 4 层到第 7 层的服务,并为日志和分析平台 [NetScaler 管理和分析系统](https://www.citrix.com/blogs/2016/05/24/introducing-the-next-generation-netscaler-management-and-analytics-system/) 提供高效的度量数据。 + + +我希望我们所有与技术合作伙伴一起工作的经验都能像与 GCP 一起工作一样好。我们有一个列表,包含支持我们的用例所需要解决的问题。我们能够快速协作形成解决方案。为了解决这些问题,GCP 团队提供了深入的技术支持,与 Citrix 合作,从而使得 NetScaler CPX 能够在每台主机上作为客户端代理启动运行。 + + +接下来,需要在 GCP 入口负载均衡器的数据路径中插入 NetScaler CPX,使 NetScaler CPX 能够将流量分散到前端 web 服务器。NetScaler 团队进行了修改,以便 NetScaler CPX 监听 API 服务器事件,并配置自己来创建 VIP、IP 表规则和服务器规则,以便跨前端应用程序接收流量和负载均衡。谷歌云平台团队提供反馈和帮助,验证为克服技术障碍所做的修改。完成了! + + +NetScaler CPX 用例在 [Kubernetes 1.3](https://kubernetes.io/blog/2016/07/kubernets-1.3 - bridge -cloud-native-and-enterprise-workload) 中提供支持。Citrix 的客户和更广泛的企业市场将有机会基于 Kubernetes 享用 NetScaler 服务,从而降低将工作负载转移到云平台的阻力。  + + +您可以在[此处](https://www.citrix.com/networking/microservices.html)了解有关 NetScaler CPX 的更多信息。 + + +_ -- Mikko Disini,Citrix Systems NetScaler 产品管理总监 + diff --git a/content/zh/blog/_posts/2016-07-00-Dashboard-Web-Interface-For-Kubernetes.md b/content/zh/blog/_posts/2016-07-00-Dashboard-Web-Interface-For-Kubernetes.md new file mode 100644 index 0000000000000..467d169c0fb31 --- /dev/null +++ b/content/zh/blog/_posts/2016-07-00-Dashboard-Web-Interface-For-Kubernetes.md @@ -0,0 +1,139 @@ +--- +title: " Dashboard - Kubernetes 的全功能 Web 界面 " +date: 2016-07-15 +slug: dashboard-web-interface-for-kubernetes +url: /blog/2016/07/Dashboard-Web-Interface-For-Kubernetes +--- + + + + + +_编者按:这篇文章是[一系列深入的文章](https://kubernetes.io/blog/2016/07/five-days-of-kubernetes-1.3) 中关于Kubernetes 1.3的新内容的一部分_ +[Kubernetes Dashboard](http://github.com/kubernetes/dashboard)是一个旨在为 Kubernetes 世界带来通用监控和操作 Web 界面的项目。三个月前,我们[发布](https://kubernetes.io/blog/2016/04/building-awesome-user-interfaces-for-kubernetes)第一个面向生产的版本,从那时起 dashboard 已经做了大量的改进。在一个 UI 中,您可以在不离开浏览器的情况下,与 Kubernetes 集群执行大多数可能的交互。这篇博客文章分解了最新版本中引入的新功能,并概述了未来的路线图。 + + + +**全功能的 Dashboard** + +由于社区和项目成员的大量贡献,我们能够为[Kubernetes 1.3发行版](https://kubernetes.io/blog/2016/07/kubernetes-1.3-bridging-cloud-native-and-enterprise-workloads)提供许多新功能。我们一直在认真听取用户的反馈(参见[摘要信息图表](http://static.lwy.io/img/kubernetes_dashboard_infographic.png)),并解决了最高优先级的请求和难点。 +--> + + + +Dashboard UI 现在处理所有工作负载资源。这意味着无论您运行什么工作负载类型,它都在 web 界面中可见,并且您可以对其进行操作更改。例如,可以使用[Pet Sets](/docs/user-guide/petset/)修改有状态的 mysql 安装,使用部署对 web 服务器进行滚动更新,或使用守护程序安装群集监视。 + + + + [![](https://lh3.googleusercontent.com/p9bMGxPx4jE6_Z2KB-MktmyuAxyFst-bEk29M_Bn0Bj5ul7uzinH6u5WjHsMmqhGvBwlABZt06dwQ5qkBZiLq_EM1oddCmpwChvXDNXZypaS5l8uzkKuZj3PBUmzTQT4dgDxSXgz) ](https://lh3.googleusercontent.com/p9bMGxPx4jE6_Z2KB-MktmyuAxyFst-bEk29M_Bn0Bj5ul7uzinH6u5WjHsMmqhGvBwlABZt06dwQ5qkBZiLq_EM1oddCmpwChvXDNXZypaS5l8uzkKuZj3PBUmzTQT4dgDxSXgz) + + + +除了查看资源外,还可以创建、编辑、更新和删除资源。这个特性支持许多用例。例如,您可以杀死一个失败的 pod,对部署进行滚动更新,或者只组织资源。您还可以导出和导入云应用程序的 yaml 配置文件,并将它们存储在版本控制系统中。 + + + + ![](https://lh6.googleusercontent.com/zz-qjNcGgvWXrK1LIipUdIdPyeWJ1EyPVJxRnSvI6pMcLBkxDxpQt-ObsIiZsS_X0RjVBWtXYO5TCvhsymb__CGXFzKuPUnUrB4HKnAMsxtYdWLwMmHEb8c9P9Chzlo5ePHRKf5O) + + + +这个版本包括一个用于管理和操作用例的集群节点的 beta 视图。UI 列出集群中的所有节点,以便进行总体分析和快速筛选有问题的节点。details 视图显示有关该节点的所有信息以及指向在其上运行的 pod 的链接。 + + + + ![](https://lh6.googleusercontent.com/3CSTUy-8Tz-yAL9tCqxNUqMcWJYKK0dwk7kidE9zy-L-sXFiD4A4Y2LKEqbJKgI6Fl6xbzYxsziI8dULVXPJbu6eU0ci7hNtqi3tTuhdbVD6CG3EXw151fvt2MQuqumHRbab6g-_) + + + +我们随发行版提供的还有许多小范围的新功能,即:支持命名空间资源、国际化、性能改进和许多错误修复(请参阅[发行说明](https://github.com/kubernetes/dashboard/releases/tag/v1.1.0)中的更多内容)。所有这些改进都会带来更好、更简单的产品用户体验。 + + + +**Future Work** + + + +该团队对跨越多个用例的未来有着雄心勃勃的计划。我们还对所有功能请求开放,您可以在我们的[问题跟踪程序](https://github.com/kubernetes/dashboard/issues)上发布这些请求。 + + + +以下是我们接下来几个月的重点领域: + +- [Handle more Kubernetes resources](https://github.com/kubernetes/dashboard/issues/961) - 显示群集用户可能与之交互的所有资源。一旦完成,dashboard 就可以完全替代cli。 +- [Monitoring and troubleshooting](https://github.com/kubernetes/dashboard/issues/962) - 将资源使用统计信息/图表添加到 Dashboard 中显示的对象。这个重点领域将允许对云应用程序进行可操作的调试和故障排除。 +- [Security, auth and logging in](https://github.com/kubernetes/dashboard/issues/964) - 使仪表板可从群集外部的网络访问,并使用自定义身份验证系统。 + + + +**联系我们** + + + +我们很乐意与您交谈并听取您的反馈! + +- 请在[SIG-UI邮件列表](https://groups.google.com/forum/向我们发送电子邮件!论坛/kubernetes sig ui) +- 在 kubernetes slack 上与我们聊天。[#SIG-UI channel](https://kubernetes.slack.com/messages/sig-ui/) +- 参加我们的会议:东部时间下午4点。请参阅[SIG-UI日历](https://calendar.google.com/calendar/embed?src=google.com_52lm43hc2kur57dgkibltqc6kc%40group.calendar.google.com&ctz=Europe/Warsaw)了解详细信息。 diff --git a/content/zh/blog/_posts/2016-07-00-Oh-The-Places-You-Will-Go.md b/content/zh/blog/_posts/2016-07-00-Oh-The-Places-You-Will-Go.md new file mode 100644 index 0000000000000..95adefc352ee1 --- /dev/null +++ b/content/zh/blog/_posts/2016-07-00-Oh-The-Places-You-Will-Go.md @@ -0,0 +1,89 @@ +--- +title: " Kubernetes 生日快乐。哦,这是你要去的地方! " +date: 2016-07-21 +slug: oh-the-places-you-will-go +url: /blog/2016/07/Oh-The-Places-You-Will-Go +--- + + + + + +_编者按,今天的嘉宾帖子来自一位独立的 kubernetes 撰稿人 Justin Santa Barbara,分享了他对项目从一开始到未来发展的思考。_ + +**亲爱的 K8s,** + +_很难相信你是唯一的一个 - 成长这么快的。在你一岁生日的时候,我想我可以写一个小纸条,告诉你为什么我在你出生的时候那么兴奋,为什么我觉得很幸运能成为抚养你长大的一员,为什么我渴望看到你继续成长!_ + + + +_--Justin_ + +你从一个优秀的基础 - 良好的声明性功能开始,它是围绕一个具有良好定义的模式和机制的坚实的 API 构建的,这样我们就可以向前发展了。果然,在你的第一年里,你增长得如此之快:autoscaling、HTTP load-balancing support (Ingress)、support for persistent workloads including clustered databases (PetSets)。你已经和更多的云交了朋友(欢迎 azure 和 openstack 加入家庭),甚至开始跨越区域和集群(Federation)。这些只是一些最明显的变化 - 在你的大脑里发生了太多的变化! + +我觉得你一直保持开放的态度真是太好了 - 你好像把所有的东西都写在 github 上 - 不管是好是坏。我想我们在这方面都学到了很多,比如让工程师做缩放声明的风险,然后在没有完全相同的精确性和严谨性框架的情况下,将这些声明与索赔进行权衡。但我很自豪你选择了不降低你的标准,而是上升到挑战,只是跑得更快 - 这可能不是最现实的办法,但这是唯一的方式能移动山! + + + +然而,不知何故,你已经设法避免了许多其他开源软件陷入的共同死胡同,特别是当那些项目越来越大,开发人员最终要做的比直接使用它更多的时候。你是怎么做到的?有一个很可能是虚构的故事,讲的是 IBM 的一名员工犯了一个巨大的错误,被传唤去见大老板,希望被解雇,却被告知“我们刚刚花了几百万美元培训你。我们为什么要解雇你?“。尽管谷歌对你进行了大量的投资(包括 redhat 和其他公司),但我有时想知道,我们正在避免的错误是否更有价值。有一个非常开放的开发过程,但也有一个“oracle”,它有时会通过告诉我们两年后如果我们做一个特定的设计决策会发生什么来纠正错误。这是你应该听的父母! + + + +所以,尽管你只有一岁,你真的有一个[旧灵魂](http://queue.acm.org/detail.cfm?ID=2898444)。我只是[很多人抚养你]中的一员(https://kubernetes.io/blog/2016/07/happy-k8sbday-1),但对我来说,能够与那些建立了这些令人难以置信的系统并拥有所有这些领域知识的人一起工作是一次极好的学习经历。然而,因为我们是白手起家(而不是采用现有的 Borg 代码),我们处于同一水平,仍然可以就如何培养你进行真正的讨论。好吧,至少和我们的水平一样接近,但值得称赞的是,他们都太好了,从来没提过! + +如果我选择两个聪明人做出的明智决定: + + + +- 标签和选择器给我们声明性的“pointers”,所以我们可以说“为什么”我们想要东西,而不是直接列出东西。这是如何扩展到[伟大高度]的秘密(https://kubernetes.io/blog/2016/07/thousand-instances-of-cassandra-using-kubernetes-pet-set);不是命名每一步,而是说“像第一步一样多走一千步”。 +- 控制器是状态同步器:我们指定目标,您的控制器将不遗余力地工作,使系统达到该状态。它们工作在强类型 API 基础上,并且贯穿整个代码,因此 Kubernetes 比一个大的程序多一百个小程序。仅仅从技术上扩展到数千个节点是不够的;这个项目还必须扩展到数千个开发人员和特性;控制器帮助我们达到目的。 + + + +等等我们就走!我们将取代那些控制器,建立更多,API 基金会让我们构建任何我们可以用这种方式表达的东西 - 大多数东西只是标签或注释远离!但你的思想不会由语言来定义:有了第三方资源,你可以表达任何你选择的东西。现在我们可以不用在 Kubernetes 建造Kubernetes 了,创造出与其他任何东西一样感觉是 Kubernetes 的一部分的东西。最近添加的许多功能,如ingress、DNS integration、autoscaling and network policies ,都已经完成或可以通过这种方式完成。最终,在这些事情发生之前很难想象你会是怎样的一个人,但是明天的标准功能可以从今天开始,没有任何障碍或看门人,甚至对一个听众来说也是这样。 + +所以我期待着看到越来越多的增长发生在离 Kubernetes 核心越来越远的地方。我们必须通过这些阶段来工作;从需要在 kubernetes 内核中发生的事情开始——比如用部署替换复制控制器。现在我们开始构建不需要核心更改的东西。但我们仍然在讨论基础设施和应用程序。接下来真正有趣的是:当我们开始构建依赖于 kubernetes api 的应用程序时。我们一直有使用 kubernetes api 进行自组装的 cassandra 示例,但我们还没有真正开始更广泛地探讨这个问题。正如 S3 APIs 改变了我们构建记忆事物的方式一样,我认为 k8s APIs 也将改变我们构建思考事物的方式。 + + + +所以我很期待你的二岁生日:我可以试着预测你那时的样子,但我知道你会超越我所能想象的最大胆的东西。哦,这是你要去的地方! + + +_-- Justin Santa Barbara, 独立的 Kubernetes 贡献者_ diff --git a/content/zh/blog/_posts/2017-10-00-Five-Days-Of-Kubernetes-18.md b/content/zh/blog/_posts/2017-10-00-Five-Days-Of-Kubernetes-18.md new file mode 100644 index 0000000000000..8fb8d01ef9fb0 --- /dev/null +++ b/content/zh/blog/_posts/2017-10-00-Five-Days-Of-Kubernetes-18.md @@ -0,0 +1,72 @@ +--- +title: " Kubernetes 1.8 的五天 " +date: 2017-10-24 +slug: five-days-of-kubernetes-18 +url: /blog/2017/10/Five-Days-Of-Kubernetes-18 +--- + + + + +Kubernetes 1.8 是现场直播,数百名贡献者在这个最新版本中推出了成千上万的提交。 + + +社区已经有超过 66,000 个提交在主仓库,并在主仓库之外继续快速增长,这标志着该项目日益成熟和稳定。仅 v1.7.0 到 v1.8.0,社区就记录了所有仓库的超过 120,000 次提交和 17839 次提交。 + + +在拥有 1400 多名贡献者,并且不断发展壮大的社区的帮助下,我们合并了 3000 多个 PR,并发布了 5000 多个提交,最后的 Kubernetes 1.8 在安全和工作负载方面添加了很多的更新。 +这一切都表明稳定性的提高,这是我们整个项目关注成熟[流程](https://github.com/kubernetes/sig-release)、形式化[架构](https://github.com/kubernetes/community/tree/master/sig-architecture)和加强 Kubernetes 的[治理模型](https://github.com/kubernetes/community/tree/master/community/elections/2017)的结果。 + + +虽然有很多改进,但我们在下面列出的这一系列深度文章中突出了一些关键特性。[跟随](https://twitter.com/kubernetesio)并了解存储,安全等方面的新功能和改进功能。 + + + +**第一天:** [Kubernetes 1.8 的五天](https://kubernetes.io/blog/2017/10/five-days-of-kubernetes-18) +**第二天:** [kubeadm v1.8 为 Kubernetes 集群引入了简单的升级](https://kubernetes.io/blog/2017/10/kubeadm-v18-released) +**第三天:** [Kubernetes v1.8 回顾:提升一个 Kubernetes 需要一个 Village](https://kubernetes.io/blog/2017/10/it-takes-village-to-raise-kubernetes) +**第四天:** [使用 RBAC,一般在 Kubernetes v1.8 中提供](https://kubernetes.io/blog/2017/10/using-rbac-generally-available-18) +**第五天:** [在 Kubernetes 执行网络策略](https://kubernetes.io/blog/2017/10/enforcing-network-policies-in-kubernetes) + + + +**链接** + + + +- 在 [Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes) 上发布问题(或回答问题) +- 加入 [K8sPort](http://k8sport.org/) 布道师的社区门户网站 +- 在 Twitter [@Kubernetesio](https://twitter.com/kubernetesio) 关注我们以获取最新更新 +- 与 [Slack](http://slack.k8s.io/) 上的社区联系 +- 参与 [GitHub](https://github.com/kubernetes/kubernetes) 上的 Kubernetes 项目 + + diff --git a/content/zh/blog/_posts/2017-11-00-Autoscaling-In-Kubernetes.md b/content/zh/blog/_posts/2017-11-00-Autoscaling-In-Kubernetes.md new file mode 100644 index 0000000000000..87c9ccd74b5fa --- /dev/null +++ b/content/zh/blog/_posts/2017-11-00-Autoscaling-In-Kubernetes.md @@ -0,0 +1,32 @@ +--- +title: " Kubernetes 中自动缩放 " +date: 2017-11-17 +slug: autoscaling-in-kubernetes +url: /blog/2017/11/Autoscaling-In-Kubernetes +--- + + + + +Kubernetes 允许开发人员根据当前的流量和负载自动调整集群大小和 pod 副本的数量。这些调整减少了未使用节点的数量,节省了资金和资源。 +在这次演讲中,谷歌的 Marcin Wielgus 将带领您了解 Kubernetes 中 pod 和 node 自动调焦的当前状态:它是如何工作的,以及如何使用它,包括在生产应用程序中部署的最佳实践。 + + +喜欢这个演讲吗? 12 月 6 日至 8 日,在 Austin 参加 KubeCon 关于扩展和自动化您的 Kubernetes 集群的更令人兴奋的会议。[现在注册](https://www.eventbrite.com/e/kubecon-cloudnativecon-north-america-registration-37824050754?_ga=2.9666039.317115486.1510003873-1623727562.1496428006)。 + + +一定要查看由 Ron Lipke, Gannet/USA Today Network, 平台即服务高级开发人员,在[公共云中自动化和测试产品就绪的 Kubernetes 集群](http://sched.co/CU64)。 + diff --git a/content/zh/blog/_posts/2018-05-01-developing-on-kubernetes.md b/content/zh/blog/_posts/2018-05-01-developing-on-kubernetes.md new file mode 100644 index 0000000000000..5d31031ec7f10 --- /dev/null +++ b/content/zh/blog/_posts/2018-05-01-developing-on-kubernetes.md @@ -0,0 +1,728 @@ +--- +title: 在 Kubernetes 上开发 +date: 2018-05-01 +slug: developing-on-kubernetes +--- + + + + +**作者**: [Michael Hausenblas](https://twitter.com/mhausenblas) (Red Hat), [Ilya Dmitrichenko](https://twitter.com/errordeveloper) (Weaveworks) + + + +您将如何开发一个 Kubernates 应用?也就是说,您如何编写并测试一个要在 Kubernates 上运行的应用程序?本文将重点介绍在独自开发或者团队协作中,您可能希望了解到的为了成功编写 Kubernetes 应用程序而需面临的挑战,工具和方法。 + + + +我们假定您是一位开发人员,有您钟爱的编程语言,编辑器/IDE(集成开发环境),以及可用的测试框架。在针对 Kubernates 开发应用时,最重要的目标是减少对当前工作流程的影响,改变越少越好,尽量做到最小。举个例子,如果您是 Node.js 开发人员,习惯于那种热重载的环境 - 也就是说您在编辑器里一做保存,正在运行的程序就会自动更新 - 那么跟容器、容器镜像或者镜像仓库打交道,又或是跟 Kubernetes 部署、triggers 以及更多头疼东西打交道,不仅会让人难以招架也真的会让开发过程完全失去乐趣。 + + + +在下文中,我们将首先讨论 Kubernetes 总体开发环境,然后回顾常用工具,最后进行三个示例性工具的实践演练。这些工具允许针对 Kubernetes 进行本地应用程序的开发和迭代。 + + + +## 您的集群运行在哪里? + + + +作为开发人员,您既需要考虑所针对开发的 Kubernetes 集群运行在哪里,也需要思考开发环境如何配置。概念上,有四种开发模式: + +![Dev Modes](/images/blog/2018-05-01-developing-on-kubernetes/dok-devmodes_preview.png) + + + +许多工具支持纯 offline 开发,包括 Minikube、Docker(Mac 版/Windows 版)、Minishift 以及下文中我们将详细讨论的几种。有时,比如说在一个微服务系统中,已经有若干微服务在运行,proxied 模式(通过转发把数据流传进传出集群)就非常合适,Telepresence 就是此类工具的一个实例。live 模式,本质上是您基于一个远程集群进行构建和部署。最后,纯 online 模式意味着您的开发环境和运行集群都是远程的,典型的例子是 [Eclipse Che](https://www.eclipse.org/che/docs/kubernetes-single-user.html) 或者 [Cloud 9](https://github.com/errordeveloper/k9c)。现在让我们仔细看看离线开发的基础:在本地运行 Kubernetes。 + + + +[Minikube](/docs/getting-started-guides/minikube/) 在更加喜欢于本地 VM 上运行 Kubernetes 的开发人员中,非常受欢迎。不久前,Docker 的 [Mac](https://docs.docker.com/docker-for-mac/kubernetes/) 版和 [Windows](https://docs.docker.com/docker-for-windows/kubernetes/) 版,都试验性地开始自带 Kubernetes(需要下载 “edge” 安装包)。在两者之间,以下原因也许会促使您选择 Minikube 而不是 Docker 桌面版: + + + +* 您已经安装了 Minikube 并且它运行良好 +* 您想等到 Docker 出稳定版本 +* 您是 Linux 桌面用户 +* 您是 Windows 用户,但是没有配有 Hyper-V 的 Windows 10 Pro + + + +运行一个本地集群,开发人员可以离线工作,不用支付云服务。云服务收费一般不会太高,并且免费的等级也有,但是一些开发人员不喜欢为了使用云服务而必须得到经理的批准,也不愿意支付意想不到的费用,比如说忘了下线而集群在周末也在运转。 + + + +有些开发人员却更喜欢远程的 Kubernetes 集群,这样他们通常可以获得更大的计算能力和存储容量,也简化了协同工作流程。您可以更容易的拉上一个同事来帮您调试,或者在团队内共享一个应用的使用。再者,对某些开发人员来说,尽可能的让开发环境类似生产环境至关重要,尤其是您依赖外部厂商的云服务时,如:专有数据库、云对象存储、消息队列、外商的负载均衡器或者邮件投递系统。 + + + +总之,无论您选择本地或者远程集群,理由都足够多。这很大程度上取决于您所处的阶段:从早期的原型设计/单人开发到后期面对一批稳定微服务的集成。 + + + +既然您已经了解到运行环境的基本选项,那么我们就接着讨论如何迭代式的开发并部署您的应用。 + + + +## 常用工具 + + + +我们现在回顾既可以允许您可以在 Kubernetes 上开发应用程序又尽可能最小地改变您现有的工作流程的一些工具。我们致力于提供一份不偏不倚的描述,也会提及使用某个工具将会意味着什么。 + + + +请注意这很棘手,因为即使在成熟定型的技术中做选择,比如说在 JSON、YAML、XML、REST、gRPC 或者 SOAP 之间做选择,很大程度也取决于您的背景、喜好以及公司环境。在 Kubernetes 生态系统内比较各种工具就更加困难,因为技术发展太快,几乎每周都有新工具面市;举个例子,仅在准备这篇博客的期间,[Gitkube](https://gitkube.sh/) 和 [Watchpod](https://github.com/MinikubeAddon/watchpod) 相继出品。为了进一步覆盖到这些新的,以及一些相关的已推出的工具,例如 [Weave Flux](https://github.com/weaveworks/flux) 和 OpenShift 的 [S2I](https://docs.openshift.com/container-platform/3.9/creating_images/s2i.html),我们计划再写一篇跟进的博客。 + +### Draft + + + + +[Draft](https://github.com/Azure/draft) 旨在帮助您将任何应用程序部署到 Kubernetes。它能够检测到您的应用所使用的编程语言,并且生成一份 Dockerfile 和 Helm 图表。然后它替您启动构建并且依照 Helm 图表把所生产的镜像部署到目标集群。它也可以让您很容易地设置到 localhost 的端口映射。 + + + +这意味着: + + +* 用户可以任意地自定义 Helm 图表和 Dockerfile 模版,或者甚至创建一个 [custom pack](https://github.com/Azure/draft/blob/master/docs/reference/dep-003.md)(使用 Dockerfile、Helm 图表以及其他)以备后用 + + +* 要想理解一个应用应该怎么构建并不容易,在某些情况下,用户也许需要修改 Draft 生成的 Dockerfile 和 Heml 图表 + + +* 如果使用 [Draft version 0.12.0](https://github.com/Azure/draft/releases/tag/v0.12.0)1 或者更老版本,每一次用户想要测试一个改动,他们需要等 Draft 把代码拷贝到集群,运行构建,推送镜像并且发布更新后的图表;这些步骤可能进行得很快,但是每一次用户的改动都会产生一个镜像(无论是否提交到 git ) + + +* 在 Draft 0.12.0版本,构建是本地进行的 +* 用户不能选择 Helm 以外的工具进行部署 +* 它可以监控本地的改动并且触发部署,但是这个功能默认是关闭的 + + +* 它允许开发人员使用本地或者远程的 Kubernates 集群 +* 如何部署到生产环境取决于用户, Draft 的作者推荐了他们的另一个项目 - Brigade +* 可以代替 Skaffold, 并且可以和 Squash 一起使用 + + + +更多信息: + +* [Draft: Kubernetes container development made easy](https://kubernetes.io/blog/2017/05/draft-kubernetes-container-development) +* [Getting Started Guide](https://github.com/Azure/draft/blob/master/docs/getting-started.md) + +【1】:此处疑为 0.11.0,因为 0.12.0 已经支持本地构建,见下一条 + +### Skaffold + + + +[Skaffold](https://github.com/GoogleCloudPlatform/skaffold) 让 CI 集成具有可移植性的,它允许用户采用不同的构建系统,镜像仓库和部署工具。它不同于 Draft,同时也具有一定的可比性。它具有生成系统清单的基本能力,但那不是一个重要功能。Skaffold 易于扩展,允许用户在构建和部署应用的每一步选取相应的工具。 + + + +这意味着: + + +* 模块化设计 +* 不依赖于 CI,用户不需要 Docker 或者 Kubernetes 插件 +* 没有 CI 也可以工作,也就是说,可以在开发人员的电脑上工作 +* 它可以监控本地的改动并且触发部署 + + +* 它允许开发人员使用本地或者远程的 Kubernetes 集群 +* 它可以用于部署生产环境,用户可以精确配置,也可以为每一套目标环境提供不同的生产线 +* 可以代替 Draft,并且和其他工具一起使用 + + + +更多信息: + +* [Introducing Skaffold: Easy and repeatable Kubernetes development](https://cloudplatform.googleblog.com/2018/03/introducing-Skaffold-Easy-and-repeatable-Kubernetes-development.html) +* [Getting Started Guide](https://github.com/GoogleCloudPlatform/skaffold#getting-started-with-local-tooling) + +### Squash + + +[Squash](https://github.com/solo-io/squash) 包含一个与 Kubernetes 全面集成的调试服务器,以及一个 IDE 插件。它允许您插入断点和所有的调试操作,就像您所习惯的使用 IDE 调试一个程序一般。它允许您将调试器应用到 Kubernetes 集群中运行的 pod 上,从而让您可以使用 IDE 调试 Kubernetes 集群。 + + + +这意味着: + + +* 不依赖您选择的其它工具 +* 需要一组特权 DaemonSet +* 可以和流行 IDE 集成 +* 支持 Go、Python、Node.js、Java 和 gdb + + +* 用户必须确保容器中的应用程序使编译时使用了调试符号 +* 可与此处描述的任何其他工具结合使用 +* 它可以与本地或远程 Kubernetes 集群一起使用 + + + +更多信息: + +* [Squash: A Debugger for Kubernetes Apps](https://www.youtube.com/watch?v=5TrV3qzXlgI) +* [Getting Started Guide](https://github.com/solo-io/squash/blob/master/docs/getting-started.md) + +### Telepresence + + +[Telepresence](https://www.telepresence.io/) 使用双向代理将开发人员工作站上运行的容器与远程 Kubernetes 集群连接起来,并模拟集群内环境以及提供对配置映射和机密的访问。它消除了将应用部署到集群的需要,并利用本地容器抽象出网络和文件系统接口,以使其看起来应用好像就在集群中运行,从而改进容器应用程序开发的迭代时间。 + + + +这意味着: + + +* 它不依赖于其它您选取的工具 +* 可以同 Squash 一起使用,但是 Squash 必须用于调试集群中的 pods,而传统/本地调试器需要用于调试通过 Telepresence 连接到集群的本地容器 +* Telepresence 会产生一些网络延迟 + + +* 它通过辅助进程提供连接 - sshuttle,基于SSH的一个工具 +* 还提供了使用 LD_PRELOAD/DYLD_INSERT_LIBRARIES 的更具侵入性的依赖注入模式 +* 它最常用于远程 Kubernetes 集群,但也可以与本地集群一起使用 + + + +更多信息: + +* [Telepresence: fast, realistic local development for Kubernetes microservices](https://www.telepresence.io/) +* [Getting Started Guide](https://www.telepresence.io/tutorials/docker) +* [How It Works](https://www.telepresence.io/discussion/how-it-works) + +### Ksync + + + + +[Ksync](https://github.com/vapor-ware/ksync) 在本地计算机和运行在 Kubernetes 中的容器之间同步应用程序代码(和配置),类似于 [oc rsync](https://docs.openshift.com/container-platform/3.9/dev_guide/copy_files_to_container.html) 在 OpenShift 中的角色。它旨在通过消除构建和部署步骤来缩短应用程序开发的迭代时间。 + + + + +这意味着: + + +* 它绕过容器图像构建和修订控制 +* 使用编译语言的用户必须在 pod(TBC)内运行构建 +* 双向同步 - 远程文件会复制到本地目录 +* 每次更新远程文件系统时都会重启容器 +* 无安全功能 - 仅限开发 + + +* 使用 [Syncthing](https://github.com/syncthing/syncthing),一个用于点对点同步的 Go 语言库 +* 需要一个在集群中运行的特权 DaemonSet +* Node 必须使用带有 overlayfs2 的 Docker - 在写作本文时,尚不支持其他 CRI 实现 + + + +更多信息: + +* [Getting Started Guide](https://github.com/vapor-ware/ksync#getting-started) +* [How It Works](https://github.com/vapor-ware/ksync/blob/master/docs/architecture.md) +* [Katacoda scenario to try out ksync in your browser](https://www.katacoda.com/vaporio/scenarios/ksync) +* [Syncthing Specification](https://docs.syncthing.net/specs/) + + + +## 实践演练 + + + + +我们接下来用于练习使用工具的应用是一个简单的[股市模拟器](https://github.com/kubernauts/dok-example-us),包含两个微服务: + + + +* `stock-gen`(股市数据生成器)微服务是用 Go 编写的,随机生成股票数据并通过 HTTP 端点 `/ stockdata` 公开 +* 第二个微服务,`stock-con`(股市数据消费者)是一个 Node.js 应用程序,它使用来自 `stock-gen` 的股票数据流,并通过 HTTP 端点 `/average/$SYMBOL` 提供股价移动平均线,也提供一个健康检查端点 `/healthz`。 + + + +总体上,此应用的默认配置如下图所示: + +![Default Setup](/images/blog/2018-05-01-developing-on-kubernetes/dok-architecture_preview.png) + + + +在下文中,我们将选取以上讨论的代表性工具进行实践演练:ksync,具有本地构建的 Minikube 以及 Skaffold。对于每个工具,我们执行以下操作: + + + +* 设置相应的工具,包括部署准备和 `stock-con` 微服务数据的本地读取 +* 执行代码更新,即更改 `stock-con` 微服务的 `/healthz` 端点的源代码并观察网页刷新 + + + +请注意,我们一直使用 Minikube 的本地 Kubernetes 集群,但是您也可以使用 ksync 和 Skaffold 的远程集群跟随练习。 + + + +### 实践演练:ksync + + + +作为准备,安装 [ksync](https://vapor-ware.github.io/ksync/#installation),然后执行以下步骤配置开发环境: + +``` +$ mkdir -p $(pwd)/ksync +$ kubectl create namespace dok +$ ksync init -n dok +``` + + + +完成基本设置后,我们可以告诉 ksync 的本地客户端监控 Kubernetes 的某个命名空间,然后我们创建一个规范来定义我们想要同步的文件夹(本地的 `$(pwd)/ksync` 和容器中的 `/ app` )。请注意,目标 pod 是用 selector 参数指定: + +``` +$ ksync watch -n dok +$ ksync create -n dok --selector=app=stock-con $(pwd)/ksync /app +$ ksync get -n dok +``` + + + +现在我们部署股价数据生成器和股价数据消费者微服务: + +``` +$ kubectl -n=dok apply \ + -f https://raw.githubusercontent.com/kubernauts/dok-example-us/master/stock-gen/app.yaml +$ kubectl -n=dok apply \ + -f https://raw.githubusercontent.com/kubernauts/dok-example-us/master/stock-con/app.yaml +``` + + + +一旦两个部署建好并且 pod 开始运行,我们转发 `stock-con` 服务以供本地读取(另开一个终端窗口): + +``` +$ kubectl get -n dok po --selector=app=stock-con \ + -o=custom-columns=:metadata.name --no-headers | \ + xargs -IPOD kubectl -n dok port-forward POD 9898:9898 +``` + + + +这样,通过定期查询 `healthz` 端点,我们就应该能够从本地机器上读取 `stock-con` 服务,查询命令如下(在一个单独的终端窗口): + +``` +$ watch curl localhost:9898/healthz +``` + + + +现在,改动 `ksync/stock-con` 目录中的代码,例如改动 [`service.js` 中定义的 `/healthz` 端点代码](https://github.com/kubernauts/dok-example-us/blob/2334ee8fb11f8813370122bd46285cf45bdd4c48/stock-con/service.js#L52),在其 JSON 形式的响应中新添一个字段并观察 pod 如何更新以及 `curl localhost:9898/healthz` 命令的输出发生何种变化。总的来说,您最后应该看到类似的内容: + + +![Preview](/images/blog/2018-05-01-developing-on-kubernetes/dok-ksync_preview.png) + + + + +### 实践演练:带本地构建的 Minikube + + + + +对于以下内容,您需要启动并运行 Minikube,我们将利用 Minikube 自带的 Docker daemon 在本地构建镜像。作为准备,请执行以下操作 + +``` +$ git clone https://github.com/kubernauts/dok-example-us.git && cd dok-example-us +$ eval $(minikube docker-env) +$ kubectl create namespace dok +``` + + + +现在我们部署股价数据生成器和股价数据消费者微服务: + + +``` +$ kubectl -n=dok apply -f stock-gen/app.yaml +$ kubectl -n=dok apply -f stock-con/app.yaml +``` + + + +一旦两个部署建好并且 pod 开始运行,我们转发 `stock-con` 服务以供本地读取(另开一个终端窗口): + +``` +$ kubectl get -n dok po --selector=app=stock-con \ + -o=custom-columns=:metadata.name --no-headers | \ + xargs -IPOD kubectl -n dok port-forward POD 9898:9898 & +$ watch curl localhost:9898/healthz +``` + + +现在,改一下 `ksync/stock-con` 目录中的代码,例如修改 [`service.js` 中定义的 `/healthz` 端点代码](https://github.com/kubernauts/dok-example-us/blob/2334ee8fb11f8813370122bd46285cf45bdd4c48/stock-con/service.js#L52),在其 JSON 形式的响应中添加一个字段。在您更新完代码后,最后一步是构建新的容器镜像并启动新部署,如下所示: + + +``` +$ docker build -t stock-con:dev -f Dockerfile . +$ kubectl -n dok set image deployment/stock-con *=stock-con:dev +``` + + +总的来说,您最后应该看到类似的内容: + +![Local Preview](/images/blog/2018-05-01-developing-on-kubernetes/dok-minikube-localdev_preview.png) + + + +### 实践演练:Skaffold + + + +要进行此演练,首先需要安装 [Skaffold](https://github.com/GoogleContainerTools/skaffold#installation)。完成后,您可以执行以下步骤来配置开发环境: + +``` +$ git clone https://github.com/kubernauts/dok-example-us.git && cd dok-example-us +$ kubectl create namespace dok +``` + + +现在我们部署股价数据生成器(但是暂不部署股价数据消费者,此服务将使用 Skaffold 完成): + +``` +$ kubectl -n=dok apply -f stock-gen/app.yaml +``` + + + + +请注意,最初我们在执行 `skaffold dev` 时发生身份验证错误,为避免此错误需要安装[问题322](https://github.com/GoogleContainerTools/skaffold/issues/322) 中所述的修复。本质上,需要将 `〜/.docker/config.json` 的内容改为: + + +``` +{ + "auths": {} +} +``` + + + +接下来,我们需要略微改动 `stock-con/app.yaml`,这样 Skaffold 才能正常使用此文件: + + + +在 `stock-con` 部署和服务中添加一个 `namespace` 字段,其值为 `dok` + +将容器规范的 `image` 字段更改为 `quay.io/mhausenblas/stock-con`,因为 Skaffold 可以即时管理容器镜像标签。 + + +最终的 stock-con 的 `app.yaml` 文件看起来如下: + + +``` +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + labels: + app: stock-con + name: stock-con + namespace: dok +spec: + replicas: 1 + template: + metadata: + labels: + app: stock-con + spec: + containers: + - name: stock-con + image: quay.io/mhausenblas/stock-con + env: + - name: DOK_STOCKGEN_HOSTNAME + value: stock-gen + - name: DOK_STOCKGEN_PORT + value: "9999" + ports: + - containerPort: 9898 + protocol: TCP + livenessProbe: + initialDelaySeconds: 2 + periodSeconds: 5 + httpGet: + path: /healthz + port: 9898 + readinessProbe: + initialDelaySeconds: 2 + periodSeconds: 5 + httpGet: + path: /healthz + port: 9898 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: stock-con + name: stock-con + namespace: dok +spec: + type: ClusterIP + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 9898 + selector: + app: stock-con +``` + + +我们能够开始开发之前的最后一步是配置 Skaffold。因此,在 `stock-con/` 目录中创建文件 `skaffold.yaml`,其中包含以下内容: + +``` +apiVersion: skaffold/v1alpha2 +kind: Config +build: + artifacts: + - imageName: quay.io/mhausenblas/stock-con + workspace: . + docker: {} + local: {} +deploy: + kubectl: + manifests: + - app.yaml +``` + + +现在我们准备好开始开发了。为此,在 `stock-con/` 目录中执行以下命令: + +``` +$ skaffold dev +``` + + + +上面的命令将触发 `stock-con` 图像的构建和部署。一旦 `stock-con` 部署的 pod 开始运行,我们再次转发 `stock-con` 服务以供本地读取(在单独的终端窗口中)并检查 `healthz` 端点的响应: + +```bash +$ kubectl get -n dok po --selector=app=stock-con \ + -o=custom-columns=:metadata.name --no-headers | \ + xargs -IPOD kubectl -n dok port-forward POD 9898:9898 & +$ watch curl localhost:9898/healthz +``` + + +现在,如果您修改一下 `stock-con` 目录中的代码,例如 [`service.js` 中定义的 `/healthz` 端点代码](https://github.com/kubernauts/dok-example-us/blob/2334ee8fb11f8813370122bd46285cf45bdd4c48/stock-con/service.js#L52),在其 JSON 形式的响应中添加一个字段,您应该看到 Skaffold 可以检测到代码改动并创建新图像以及部署它。您的屏幕看起来应该类似这样: + + +![Skaffold Preview](/images/blog/2018-05-01-developing-on-kubernetes/dok-skaffold_preview.png) + + +至此,您应该对不同的工具如何帮您在 Kubernetes 上开发应用程序有了一定的概念,如果您有兴趣了解有关工具和/或方法的更多信息,请查看以下资源: + +* Blog post by Shahidh K Muhammed on [Draft vs Gitkube vs Helm vs Ksonnet vs Metaparticle vs Skaffold](https://blog.hasura.io/draft-vs-gitkube-vs-helm-vs-ksonnet-vs-metaparticle-vs-skaffold-f5aa9561f948) (03/2018) +* Blog post by Gergely Nemeth on [Using Kubernetes for Local Development](https://nemethgergely.com/using-kubernetes-for-local-development/index.html), with a focus on Skaffold (03/2018) +* Blog post by Richard Li on [Locally developing Kubernetes services (without waiting for a deploy)](https://hackernoon.com/locally-developing-kubernetes-services-without-waiting-for-a-deploy-f63995de7b99), with a focus on Telepresence +* Blog post by Abhishek Tiwari on [Local Development Environment for Kubernetes using Minikube](https://abhishek-tiwari.com/local-development-environment-for-kubernetes-using-minikube/) (09/2017) +* Blog post by Aymen El Amri on [Using Kubernetes for Local Development — Minikube](https://medium.com/devopslinks/using-kubernetes-minikube-for-local-development-c37c6e56e3db) (08/2017) +* Blog post by Alexis Richardson on [​GitOps - Operations by Pull Request](https://www.weave.works/blog/gitops-operations-by-pull-request) (08/2017) +* Slide deck [GitOps: Drive operations through git](https://docs.google.com/presentation/d/1d3PigRVt_m5rO89Ob2XZ16bW8lRSkHHH5k816-oMzZo/), with a focus on Gitkube by Tirumarai Selvan (03/2018) +* Slide deck [Developing apps on Kubernetes](https://speakerdeck.com/mhausenblas/developing-apps-on-kubernetes), a talk Michael Hausenblas gave at a CNCF Paris meetup (04/2018) +* YouTube videos: + * [TGI Kubernetes 029: Developing Apps with Ksync](https://www.youtube.com/watch?v=QW85Y0Ug3KY ) + * [TGI Kubernetes 030: Exploring Skaffold](https://www.youtube.com/watch?v=McwwWhCXMxc) + * [TGI Kubernetes 031: Connecting with Telepresence](https://www.youtube.com/watch?v=zezeBAJ_3w8) + * [TGI Kubernetes 033: Developing with Draft](https://www.youtube.com/watch?v=8B1D7cTMPgA) +* Raw responses to the [Kubernetes Application Survey](https://docs.google.com/spreadsheets/d/12ilRCly2eHKPuicv1P_BD6z__PXAqpiaR-tDYe2eudE/edit) 2018 by SIG Apps + + + +有了这些,我们这篇关于如何在 Kubernetes 上开发应用程序的博客就可以收尾了,希望您有所收获,如果您有反馈和/或想要指出您认为有用的工具,请通过 Twitter 告诉我们:[Ilya](https://twitter.com/errordeveloper) 和 [Michael](https://twitter.com/mhausenblas) diff --git a/content/zh/blog/_posts/2018-05-30-say-hello-to-discuss-kubernetes.md b/content/zh/blog/_posts/2018-05-30-say-hello-to-discuss-kubernetes.md new file mode 100644 index 0000000000000..eb1aba85d2b46 --- /dev/null +++ b/content/zh/blog/_posts/2018-05-30-say-hello-to-discuss-kubernetes.md @@ -0,0 +1,67 @@ +--- +title: 'Kubernetes 1 11:向 discuss kubernetes 问好' +layout: blog +date: 2018-05-30 +--- + + + + + +作者: Jorge Castro (Heptio) + + + +就一个超过 35,000 人的全球性社区而言,参与其中时沟通是非常关键的。 跟踪 Kubernetes 社区中的所有内容可能是一项艰巨的任务。 一方面,我们有官方资源,如 Stack Overflow,GitHub 和邮件列表,另一方面,我们有更多瞬时性的资源,如 Slack,你可以加入进去、与某人聊天然后各走各路。 + + + + +Slack 非常适合随意和及时的对话,并与其他社区成员保持联系,但未来很难轻易引用通信。此外,在35,000名参与者中提问并得到回答很难。邮件列表在有问题尝试联系特定人群并且想要跟踪大家的回应时非常有用,但是对于大量人员来说可能是麻烦的。 Stack Overflow 和 GitHub 非常适合在涉及代码的项目或问题上进行协作,并且如果在将来要进行搜索也很有用,但某些主题如“你最喜欢的 CI/CD 工具是什么”或“[Kubectl提示和技巧](http://discuss.kubernetes.io/t/kubectl-tips-and-tricks/192)“在那里是没有意义的。 + +虽然我们目前的各种沟通渠道对他们自己来说都很有价值,但我们发现电子邮件和实时聊天之间仍然存在差距。在网络的其他部分,许多其他开源项目,如 Docker、Mozilla、Swift、Ghost 和 Chef,已经成功地在[Discourse](http://www.discourse.org/features)之上构建社区,一个开放的讨论平台。那么,如果我们可以使用这个工具将我们的讨论结合在一个平台下,使用开放的API,或许也不会让我们的大部分信息消失在网络中呢?只有一种方法可以找到:欢迎来到[discuss.kubernetes.io](http://discuss.kubernetes.io) + + + +马上,我们有用户可以浏览的类别。检查和发布这些类别允许用户参与他们可能感兴趣的事情,而无需订阅列表。精细的通知控件允许用户只订阅他们想要的类别或标签,并允许通过电子邮件回复主题。 + +生态系统合作伙伴和开发人员现在有一个地方可以[宣布项目](http://discuss.kubernetes.io/c/announcements),他们正在为用户工作,而不会想知道它是否会在官方列表中脱离主题。我们可以让这个地方不仅仅是关于核心 Kubernetes,而是关于我们社区正在建设的数百个精彩工具。 + +这个新的社区论坛为人们提供了一个可以讨论 Kubernetes 的地方,也是开发人员在 Kubernetes 周围发布事件的声音板,同时可以搜索并且更容易被更广泛的用户访问。 + +进来看看。我们刚刚开始,所以,您可能希望从[自我介绍](http://discuss.kubernetes.io/t/introduce-yourself-here/56)开始,到处浏览。也有 [Android](http://play.google.com/store/apps/details?id=com.discourse&hl=en_US&rdid=com.discourse&pli=1) 和 [iOS](http://itunes.apple.com/us/app/discourse-app/id1173672076?mt=8) 应用下载。 + diff --git a/content/zh/blog/_posts/2018-06-06-4-years-of-k8s.md b/content/zh/blog/_posts/2018-06-06-4-years-of-k8s.md new file mode 100644 index 0000000000000..b4e118b58410d --- /dev/null +++ b/content/zh/blog/_posts/2018-06-06-4-years-of-k8s.md @@ -0,0 +1,42 @@ +--- +title: Kubernetes 这四年 +approvers: +cn-approvers: +- congfairy +layout: blog +date: 2018-06-06 +--- + + + **作者**:Joe Beda( Heptio 首席技术官兼创始人) + 2014 年 6 月 6 日,我检查了 Kubernetes 公共代码库的[第一次 commit](https://github.com/kubernetes/kubernetes/commit/2c4b3a562ce34cddc3f8218a2c4d11c7310e6d56) 。许多人会认为这是故事开始的地方。这难道不是一切开始的地方吗?但这的确不能把整个过程说清楚。 + + ![k8s_first_commit](/images/blog/2018-06-06-4-years-of-k8s/k8s-first-commit.png) + + + + 第一次 commit 涉及的人员众多,自那以后 Kubernetes 的成功归功于更大的开发者阵容。 + Kubernetes 建立在过去十年曾经在 Google 的 Borg 集群管理系统中验证过的思路之上。而 Borg 本身也是 Google 和其他公司早期努力的结果。 + 具体而言,Kubernetes 最初是从 Brendan Burns 的一些原型开始,结合我和 Craig McLuckie 正在进行的工作,以更好地将 Google 内部实践与 Google Cloud 的经验相结合。 Brendan,Craig 和我真的希望人们使用它,所以我们建议将这个原型构建为一个开源项目,将 Borg 的最佳创意带给大家。 +在我们所有人同意后,就开始着手构建这个系统了。我们采用了 Brendan 的原型(Java 语言),用 Go 语言重写了它,并且以上述核心思想去构建该系统。到这个时候,团队已经成长为包括 Ville Aikas,Tim Hockin,Brian Grant,Dawn Chen 和 Daniel Smith。一旦我们有了一些工作需求,有人必须承担一些脱敏的工作,以便为公开发布做好准备。这个角色最终由我承担。当时,我不知道这件事情的重要性,我创建了一个新的仓库,把代码搬过来,然后进行了检查。所以在我第一次提交 public commit 之前,就有工作已经启动了。 +那时 Kubernetes 的版本只是现在版本的简单雏形。核心概念已经有了,但非常原始。例如,Pods 被称为 Tasks,这在我们推广前一天就被替换。2014年6月10日 Eric Brewe 在第一届 DockerCon 上的演讲中正式发布了 Kubernetes 。您可以在此处观看该视频: + + +
+ + + + 但是,无论多么原始,这小小的一步足以激起一个开始强大而且变得更强大的社区的兴趣。在过去的四年里,Kubernetes 已经超出了我们所有人的期望。我们对 Kubernetes 社区的所有人员表示感谢。该项目所取得的成功不仅基于代码和技术,还基于一群出色的人聚集在一起所做的有意义的事情。Sarah Novotny 策划的一套 [Kubernetes 价值观](https://github.com/kubernetes/steering/blob/master/values.md)是以上最好的表现形式。 + 让我们一起期待下一个4年!🎉🎉🎉 diff --git a/content/zh/blog/_posts/2018-06-07-dynamic-ingress-kubernetes.md b/content/zh/blog/_posts/2018-06-07-dynamic-ingress-kubernetes.md new file mode 100644 index 0000000000000..bb8d7d848c1fd --- /dev/null +++ b/content/zh/blog/_posts/2018-06-07-dynamic-ingress-kubernetes.md @@ -0,0 +1,129 @@ +--- +title: 'Kubernetes 内的动态 Ingress' +layout: blog +--- + + + +作者: Richard Li (Datawire) + + + +Kubernetes 可以轻松部署由许多微服务组成的应用程序,但这种架构的关键挑战之一是动态地将流量路由到这些服务中的每一个。 +一种方法是使用 [Ambassador](https://www.getambassador.io), +一个基于 [Envoy Proxy](https://www.envoyproxy.io) 构建的 Kubernetes 原生开源 API 网关。 +Ambassador 专为动态环境而设计,这类环境中的服务可能被频繁添加或删除。 + +Ambassador 使用 Kubernetes 注解进行配置。 +注解用于配置从给定 Kubernetes 服务到特定 URL 的具体映射关系。 +每个映射中可以包括多个注解,用于配置路由。 +注解的例子有速率限制、协议、跨源请求共享(CORS)、流量影射和路由规则等。 + + + +## 一个简单的 Ambassador 示例 + +Ambassador 通常作为 Kubernetes Deployment 来安装,也可以作为 Helm Chart 使用。 +配置 Ambassador 时,请使用 Ambassador 注解创建 Kubernetes 服务。 +下面是一个例子,用来配置 Ambassador,将针对 /httpbin/ 的请求路由到公共的 httpbin.org 服务: + +``` +apiVersion: v1 +kind: Service +metadata: + name: httpbin + annotations: + getambassador.io/config: | + --- + apiVersion: ambassador/v0 + kind: Mapping + name: httpbin_mapping + prefix: /httpbin/ + service: httpbin.org:80 + host_rewrite: httpbin.org +spec: + type: ClusterIP + ports: + - port: 80 +``` + + + +例子中创建了一个 Mapping 对象,其 prefix 设置为 /httpbin/,service 名称为 httpbin.org。 +其中的 host_rewrite 注解指定 HTTP 的 host 头部字段应设置为 httpbin.org。 + + + +## Kubeflow + +[Kubeflow](https://github.com/kubeflow/kubeflow) 提供了一种简单的方法,用于在 Kubernetes 上轻松部署机器学习基础设施。 +Kubeflow 团队需要一个代理,为 Kubeflow 中所使用的各种服务提供集中化的认证和路由能力;Kubeflow 中许多服务本质上都是生命期很短的。 + +
Kubeflow architecture, pre-Ambassador
+ + + +## 服务配置 + +有了 Ambassador,Kubeflow 可以使用分布式模型进行配置。 +Ambassador 不使用集中的配置文件,而是允许每个服务通过 Kubernetes 注解在 Ambassador 中配置其路由。 +下面是一个简化的配置示例: + +``` +--- +apiVersion: ambassador/v0 +kind: Mapping +name: tfserving-mapping-test-post +prefix: /models/test/ +rewrite: /model/test/:predict +method: POST +service: test.kubeflow:8000 +``` + + + +示例中,“test” 服务使用 Ambassador 注解来为服务动态配置路由。 +所配置的路由仅在 HTTP 方法是 POST 时触发;注解中同时还给出了一条重写规则。 + + + +## Kubeflow 和 Ambassador + +通过 Ambassador,Kubeflow 可以使用 Kubernetes 注解轻松管理路由。 +Kubeflow 配置同一个 Ingress 对象,将流量定向到 Ambassador,然后根据需要创建具有 Ambassador 注解的服务,以将流量定向到特定后端。 +例如,在部署 TensorFlow 服务时,Kubeflow 会创建 Kubernetes 服务并为其添加注解, +以便用户能够在 `https:///models/<模型名称>/` 处访问到模型本身。 +Kubeflow 还可以使用 Envoy Proxy 来进行实际的 L7 路由。 +通过 Ambassador,Kubeflow 能够更充分地利用 URL 重写和基于方法的路由等额外的路由配置能力。 + +如果您对在 Kubeflow 中使用 Ambassador 感兴趣,标准的 Kubeflow 安装会自动安装和配置 Ambassador。 + +如果您有兴趣将 Ambassador 用作 API 网关或 Kubernetes 的 Ingress 解决方案, +请参阅 [Ambassador 入门指南](https://www.getambassador.io/user-guide/getting-started)。 + diff --git a/content/zh/blog/_posts/2018-08-29-kubernetes-testing-ci-automating-contributor-experience.md b/content/zh/blog/_posts/2018-08-29-kubernetes-testing-ci-automating-contributor-experience.md new file mode 100644 index 0000000000000..8720e483ea5ac --- /dev/null +++ b/content/zh/blog/_posts/2018-08-29-kubernetes-testing-ci-automating-contributor-experience.md @@ -0,0 +1,241 @@ + + +--- +layout: blog +title: '机器可以完成这项工作,一个关于 kubernetes 测试、CI 和自动化贡献者体验的故事' +date: 2019-08-29 +--- + + + +**作者**:Aaron Crickenberger(谷歌)和 Benjamin Elder(谷歌) + + + +_”大型项目有很多不那么令人兴奋,但却很辛苦的工作。比起辛苦工作,我们更重视把时间花在自动化重复性工作上,如果这项工作无法实现自动化,我们的文化就是承认并奖励所有类型的贡献。然而,英雄主义是不可持续的。“_ - [Kubernetes Community Values](https://git.k8s.io/community/values.md#automation-over-process) + + + +像许多开源项目一样,Kubernetes 托管在 GitHub 上。 如果项目位于在开发人员已经工作的地方,使用的开发人员已经知道的工具和流程,那么参与的障碍将是最低的。 因此,该项目完全接受了这项服务:它是我们工作流程,问题跟踪,文档,博客平台,团队结构等的基础。 + + + +这个策略奏效了。 它运作良好,以至于该项目迅速超越了其贡献者的人类能力。 接下来是一次令人难以置信的自动化和创新之旅。 我们不仅需要在飞行途中重建我们的飞机而不会崩溃,我们需要将其转换为火箭飞船并发射到轨道。 我们需要机器来完成这项工作。 + + + +## 工作 + + + +最初,我们关注的事实是,我们需要支持复杂的分布式系统(如 Kubernetes)所要求的大量测试。 真实世界中的故障场景必须通过端到端(e2e)测试来执行,确保正确的功能。 不幸的是,e2e 测试容易受到薄片(随机故障)的影响,并且需要花费一个小时到一天才能完成。 + + + +进一步的经验揭示了机器可以为我们工作的其他领域: + + + +* Pull Request 工作流程 + * 贡献者是否签署了我们的 CLA? + * Pull Request 通过测试吗? + * Pull Request 可以合并吗? + * 合并提交是否通过了测试? +* 鉴别分类 + * 谁应该审查 Pull Request? + * 是否有足够的信息将问题发送给合适的人? + * 问题是否依旧存在? +* 项目健康 + * 项目中发生了什么? + * 我们应该注意什么? + + + +当我们开发自动化来改善我们的情况时,我们遵循了以下几个指导原则: + + + +* 遵循适用于 Kubernetes 的推送/拉取控制循环模式 +* 首选无状态松散耦合服务 +* 更倾向于授权整个社区权利,而不是赋予少数核心贡献者权力 +* 做好自己的事,而不要重新造轮子 + + + +## 了解 Prow + + + +这促使我们创建 [Prow](https://git.k8s.io/test-infra/prow) 作为我们自动化的核心组件。 Prow有点像 [If This, Then That](https://ifttt.com/) 用于 GitHub 事件, 内置 [commands](https://prow.k8s.io/command-help), [plugins](https://prow.k8s.io/plugins), 和实用程序。 我们在 Kubernetes 之上建立了 Prow,让我们不必担心资源管理和日程安排,并确保更愉快的运营体验。 + + + +Prow 让我们做以下事情: + + + +* 允许我们的社区通过评论诸如“/priority critical-urgent”,“/assign mary”或“/close”之类的命令对 issues/Pull Requests 进行分类 +* 根据用户更改的代码数量或创建的文件自动标记 Pull Requests +* 标出长时间保持不活动状态 issues/Pull Requests +* 自动合并符合我们PR工作流程要求的 Pull Requests +* 运行定义为[Knative Builds](https://github.com/knative/build)的 Kubernetes Pods或 Jenkins jobs的 CI 作业 +* 实施组织范围和重构 GitHub 仓库策略,如[Knative Builds](https://github.com/kubernetes/test-infra/tree/master/prow/cmd/branchprotector)和[GitHub labels](https://github.com/kubernetes/test-infra/tree/master/label_sync) + + + +Prow最初由构建 Google Kubernetes Engine 的工程效率团队开发,并由 Kubernetes SIG Testing 的多个成员积极贡献。 Prow 已被其他几个开源项目采用,包括 Istio,JetStack,Knative 和 OpenShift。 [Getting started with Prow](https://github.com/kubernetes/test-infra/blob/master/prow/getting_started.md)需要一个 Kubernetes 集群和 `kubectl apply starter.yaml`(在 Kubernetes 集群上运行 pod)。 + + + +一旦我们安装了 Prow,我们就开始遇到其他的问题,因此需要额外的工具以支持 Kubernetes 所需的规模测试,包括: + + + +- [Boskos](https://github.com/kubernetes/test-infra/tree/master/boskos): 管理池中的作业资源(例如 GCP 项目),检查它们是否有工作并自动清理它们 ([with monitoring](http://velodrome.k8s.io/dashboard/db/boskos-dashboard?orgId=1)) +- [ghProxy](https://github.com/kubernetes/test-infra/tree/master/ghproxy): 优化用于 GitHub API 的反向代理 HTTP 缓存,以确保我们的令牌使用不会达到 API 限制 ([with monitoring](http://velodrome.k8s.io/dashboard/db/github-cache?refresh=1m&orgId=1)) +- [Greenhouse](https://github.com/kubernetes/test-infra/tree/master/greenhouse): 允许我们使用远程 bazel 缓存为 Pull requests 提供更快的构建和测试结果 ([with monitoring](http://velodrome.k8s.io/dashboard/db/bazel-cache?orgId=1)) +- [Splice](https://github.com/kubernetes/test-infra/tree/master/prow/cmd/splice): 允许我们批量测试和合并 Pull requests,确保我们的合并速度不仅限于我们的测试速度 +- [Tide](https://github.com/kubernetes/test-infra/tree/master/prow/cmd/tide): 允许我们合并通过 GitHub 查询选择的 Pull requests,而不是在队列中排序,允许显着更高合并速度与拼接一起 + + + +## 关注项目健康状况 + + + +随着工作流自动化的实施,我们将注意力转向了项目健康。我们选择使用 Google Cloud Storage (GCS)作为所有测试数据的真实来源,允许我们依赖已建立的基础设施,并允许社区贡献结果。然后,我们构建了各种工具来帮助个人和整个项目理解这些数据,包括: + + + +* [Gubernator](https://github.com/kubernetes/test-infra/tree/master/gubernator): 显示给定 Pull Request 的结果和测试历史 +* [Kettle](https://github.com/kubernetes/test-infra/tree/master/kettle): 将数据从 GCS 传输到可公开访问的 bigquery 数据集 +* [PR dashboard](https://k8s-gubernator.appspot.com/pr): 一个工作流程识别仪表板,允许参与者了解哪些 Pull Request 需要注意以及为什么 +* [Triage](https://storage.googleapis.com/k8s-gubernator/triage/index.html): 识别所有作业和测试中发生的常见故障 +* [Testgrid](https://k8s-testgrid.appspot.com/): 显示所有运行中给定作业的测试结果,汇总各组作业的测试结果 + + + +我们与云计算本地计算基金会(CNCF)联系,开发 DevStats,以便从我们的 GitHub 活动中收集见解,例如: + + + +* [Which prow commands are people most actively using](https://k8s.devstats.cncf.io/d/5/bot-commands-repository-groups?orgId=1) +* [PR reviews by contributor over time](https://k8s.devstats.cncf.io/d/46/pr-reviews-by-contributor?orgId=1&var-period=d7&var-repo_name=All&var-reviewers=All) +* [Time spent in each phase of our PR workflow](https://k8s.devstats.cncf.io/d/44/pr-time-to-approve-and-merge?orgId=1) + + + +## Into the Beyond + + + +今天,Kubernetes 项目跨越了5个组织125个仓库。有31个特殊利益集团和10个工作组在项目内协调发展。在过去的一年里,该项目有 [来自13800多名独立开发人员的参与](https://k8s.devstats.cncf.io/d/13/developer-activity-counts-by-repository-group?orgId=1&var-period_name=Last%20year&var-metric=contributions&var-repogroup_name=All)。 + + + +在任何给定的工作日,我们的 Prow 实例[运行超过10,000个 CI 工作](http://velodrome.k8s.io/dashboard/db/bigquery-metrics?panelId=10&fullscreen&orgId=1&from=now-6M&to=now); 从2017年3月到2018年3月,它有430万个工作岗位。 这些工作中的大多数涉及建立整个 Kubernetes 集群,并使用真实场景来实施它。 它们使我们能够确保所有受支持的 Kubernetes 版本跨云提供商,容器引擎和网络插件工作。 他们确保最新版本的 Kubernetes 能够启用各种可选功能,安全升级,满足性能要求,并跨架构工作。 + + + +今天[来自CNCF的公告](https://www.cncf.io/announcement/2018/08/29/cncf-receives-9-million-cloud-credit-grant-from-google) - 注意到 Google Cloud 有开始将 Kubernetes 项目的云资源的所有权和管理权转让给 CNCF 社区贡献者,我们很高兴能够开始另一个旅程。 允许项目基础设施由贡献者社区拥有和运营,遵循对项目其余部分有效的相同开放治理模型。 听起来令人兴奋。 请来 kubernetes.slack.com 上的 #sig-testing on kubernetes.slack.com 与我们联系。 + + + +想了解更多? 快来看看这些资源: + + + +* [Prow: Testing the way to Kubernetes Next](https://bentheelder.io/posts/prow) +* [Automation and the Kubernetes Contributor Experience](https://www.youtube.com/watch?v=BsIC7gPkH5M) diff --git a/content/zh/blog/_posts/2018-10-03-kubedirector.md b/content/zh/blog/_posts/2018-10-03-kubedirector.md new file mode 100644 index 0000000000000..e07f1bb35fde1 --- /dev/null +++ b/content/zh/blog/_posts/2018-10-03-kubedirector.md @@ -0,0 +1,306 @@ +--- +layout: blog +title: 'KubeDirector:在 Kubernetes 上运行复杂状态应用程序的简单方法' +date: 2018-10-03 +--- + + + + + +**作者**:Thomas Phelan(BlueData) + + +KubeDirector 是一个开源项目,旨在简化在 Kubernetes 上运行复杂的有状态扩展应用程序集群。KubeDirector 使用自定义资源定义(CRD) +框架构建,并利用了本地 Kubernetes API 扩展和设计哲学。这支持与 Kubernetes 用户/资源 管理以及现有客户端和工具的透明集成。 + + +我们最近[介绍了 KubeDirector 项目](https://medium.com/@thomas_phelan/operation-stateful-introducing-bluek8s-and-kubernetes-director-aa204952f619/),作为我们称为 BlueK8s 的更广泛的 Kubernetes 开源项目的一部分。我很高兴地宣布 [KubeDirector](https://github.com/bluek8s/kubedirector/) 的 +pre-alpha 代码现在已经可用。在这篇博客文章中,我将展示它是如何工作的。 + + +KubeDirector 提供以下功能: + + + +* 无需修改代码即可在 Kubernetes 上运行非云原生有状态应用程序。换句话说,不需要分解这些现有的应用程序来适应微服务设计模式。 +* 本机支持保存特定于应用程序的配置和状态。 +* 与应用程序无关的部署模式,最大限度地减少将新的有状态应用程序装载到 Kubernetes 的时间。 + + +KubeDirector 使熟悉数据密集型分布式应用程序(如 Hadoop、Spark、Cassandra、TensorFlow、Caffe2 等)的数据科学家能够在 Kubernetes 上运行这些应用程序 -- 只需极少的学习曲线,无需编写 GO 代码。由 KubeDirector 控制的应用程序由一些基本元数据和相关的配置工件包定义。应用程序元数据称为 KubeDirectorApp 资源。 + + +要了解 KubeDirector 的组件,请使用类似于以下的命令在 [GitHub](https://github.com/bluek8s/kubedirector/) 上克隆存储库: + +``` +git clone http://@github.com/bluek8s/kubedirector. +``` + + +Spark 2.2.1 应用程序的 KubeDirectorApp 定义位于文件 `kubedirector/deploy/example_catalog/cr-app-spark221e2.json` 中。 + + ``` + ~> cat kubedirector/deploy/example_catalog/cr-app-spark221e2.json + { + "apiVersion": "kubedirector.bluedata.io/v1alpha1", + "kind": "KubeDirectorApp", + "metadata": { + "name" : "spark221e2" + }, + "spec" : { + "systemctlMounts": true, + "config": { + "node_services": [ + { + "service_ids": [ + "ssh", + "spark", + "spark_master", + "spark_worker" + ], +… +``` + + +应用程序集群的配置称为 KubeDirectorCluster 资源。示例 Spark 2.2.1 集群的 KubeDirectorCluster 定义位于文件 +`kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml` 中。 + +``` +~> cat kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml +apiVersion: "kubedirector.bluedata.io/v1alpha1" +kind: "KubeDirectorCluster" +metadata: + name: "spark221e2" +spec: + app: spark221e2 + roles: + - name: controller + replicas: 1 + resources: + requests: + memory: "4Gi" + cpu: "2" + limits: + memory: "4Gi" + cpu: "2" + - name: worker + replicas: 2 + resources: + requests: + memory: "4Gi" + cpu: "2" + limits: + memory: "4Gi" + cpu: "2" + - name: jupyter +… +``` + + + +## 使用 KubeDirector 在 Kubernetes 上运行 Spark + + +使用 KubeDirector,可以轻松在 Kubernetes 上运行 Spark 集群。 + + +首先,使用命令 `kubectl version` 验证 Kubernetes(版本 1.9 或更高)是否正在运行 + +``` +~> kubectl version +Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T18:02:47Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"} +Server Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T17:53:03Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"} +``` + + +使用以下命令部署 KubeDirector 服务和示例 KubeDirectorApp 资源定义: + +``` +cd kubedirector +make deploy +``` + + +这些将启动 KubeDirector pod: + +``` +~> kubectl get pods +NAME READY STATUS RESTARTS AGE +kubedirector-58cf59869-qd9hb 1/1 Running 0 1m +``` + + +`kubectl get KubeDirectorApp` 列出中已安装的 KubeDirector 应用程序 + +``` +~> kubectl get KubeDirectorApp +NAME AGE +cassandra311 30m +spark211up 30m +spark221e2 30m +``` + + +现在,您可以使用示例 KubeDirectorCluster 文件和 `kubectl create -f deploy/example_clusters/cr-cluster-spark211up.yaml` 命令 +启动 Spark 2.2.1 集群。验证 Spark 集群已经启动: + +``` +~> kubectl get pods +NAME READY STATUS RESTARTS AGE +kubedirector-58cf59869-djdwl 1/1 Running 0 19m +spark221e2-controller-zbg4d-0 1/1 Running 0 23m +spark221e2-jupyter-2km7q-0 1/1 Running 0 23m +spark221e2-worker-4gzbz-0 1/1 Running 0 23m +spark221e2-worker-4gzbz-1 1/1 Running 0 23m +``` + + +现在运行的服务包括 Spark 服务: + +``` +~> kubectl get service +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kubedirector ClusterIP 10.98.234.194 60000/TCP 1d +kubernetes ClusterIP 10.96.0.1 443/TCP 1d +svc-spark221e2-5tg48 ClusterIP None 8888/TCP 21s +svc-spark221e2-controller-tq8d6-0 NodePort 10.104.181.123 22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP 20s +svc-spark221e2-jupyter-6989v-0 NodePort 10.105.227.249 22:30632/TCP,8888:30355/TCP 20s +svc-spark221e2-worker-d9892-0 NodePort 10.107.131.165 22:30358/TCP,8081:32144/TCP 20s +svc-spark221e2-worker-d9892-1 NodePort 10.110.88.221 22:30294/TCP,8081:31436/TCP 20s +``` + + +将浏览器指向端口 31533 连接到 Spark 主节点 UI: + +![kubedirector](/images/blog/2018-10-03-kubedirector/kubedirector.png) + + +就是这样! +事实上,在上面的例子中,我们还部署了一个 Jupyter notebook 和 Spark 集群。 + + +要启动另一个应用程序(例如 Cassandra),只需指定另一个 KubeDirectorApp 文件: + +``` +kubectl create -f deploy/example_clusters/cr-cluster-cassandra311.yaml +``` + + +查看正在运行的 Cassandra 集群: + +``` +~> kubectl get pods +NAME READY STATUS RESTARTS AGE +cassandra311-seed-v24r6-0 1/1 Running 0 1m +cassandra311-seed-v24r6-1 1/1 Running 0 1m +cassandra311-worker-rqrhl-0 1/1 Running 0 1m +cassandra311-worker-rqrhl-1 1/1 Running 0 1m +kubedirector-58cf59869-djdwl 1/1 Running 0 1d +spark221e2-controller-tq8d6-0 1/1 Running 0 22m +spark221e2-jupyter-6989v-0 1/1 Running 0 22m +spark221e2-worker-d9892-0 1/1 Running 0 22m +spark221e2-worker-d9892-1 1/1 Running 0 22m +``` + + +现在,您有一个 Spark 集群(带有 Jupyter notebook )和一个运行在 Kubernetes 上的 Cassandra 集群。 +使用 `kubectl get service` 查看服务集。 + +``` +~> kubectl get service +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kubedirector ClusterIP 10.98.234.194 60000/TCP 1d +kubernetes ClusterIP 10.96.0.1 443/TCP 1d +svc-cassandra311-seed-v24r6-0 NodePort 10.96.94.204 22:31131/TCP,9042:30739/TCP 3m +svc-cassandra311-seed-v24r6-1 NodePort 10.106.144.52 22:30373/TCP,9042:32662/TCP 3m +svc-cassandra311-vhh29 ClusterIP None 8888/TCP 3m +svc-cassandra311-worker-rqrhl-0 NodePort 10.109.61.194 22:31832/TCP,9042:31962/TCP 3m +svc-cassandra311-worker-rqrhl-1 NodePort 10.97.147.131 22:31454/TCP,9042:31170/TCP 3m +svc-spark221e2-5tg48 ClusterIP None 8888/TCP 24m +svc-spark221e2-controller-tq8d6-0 NodePort 10.104.181.123 22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP 24m +svc-spark221e2-jupyter-6989v-0 NodePort 10.105.227.249 22:30632/TCP,8888:30355/TCP 24m +svc-spark221e2-worker-d9892-0 NodePort 10.107.131.165 22:30358/TCP,8081:32144/TCP 24m +svc-spark221e2-worker-d9892-1 NodePort 10.110.88.221 22:30294/TCP,8081:31436/TCP 24m +``` + + + +## 参与其中 + + +KubeDirector 是一个完全开放源码的 Apache v2 授权项目 – 在我们称为 BlueK8s 的更广泛的计划中,它是多个开放源码项目中的第一个。 +KubeDirector 的 pre-alpha 代码刚刚发布,我们希望您加入到不断增长的开发人员、贡献者和使用者社区。 +在 Twitter 上关注 [@BlueK8s](https://twitter.com/BlueK8s/),并通过以下渠道参与: + + + +* KubeDirector [Slack 聊天室](https://join.slack.com/t/bluek8s/shared_invite/enQtNDUwMzkwODY5OTM4LTRhYmRmZmE4YzY3OGUzMjA1NDg0MDVhNDQ2MGNkYjRhM2RlMDNjMTI1NDQyMjAzZGVlMDFkNThkNGFjZGZjMGY/) +* KubeDirector [GitHub 仓库](https://github.com/bluek8s/kubedirector/) diff --git a/content/zh/blog/_posts/2018-10-11-topology-aware-volume-provisioning.md b/content/zh/blog/_posts/2018-10-11-topology-aware-volume-provisioning.md new file mode 100644 index 0000000000000..3aefd018ab019 --- /dev/null +++ b/content/zh/blog/_posts/2018-10-11-topology-aware-volume-provisioning.md @@ -0,0 +1,268 @@ +--- +layout: blog +title: 'Kubernetes 中的拓扑感知数据卷供应' +date: 2018-10-11 +--- + + + +**作者**: Michelle Au(谷歌) + + +通过提供拓扑感知动态卷供应功能,具有持久卷的多区域集群体验在 Kubernetes 1.12 中得到了改进。此功能使得 Kubernetes 在动态供应卷时能做出明智的决策,方法是从调度器获得为 Pod 提供数据卷的最佳位置。在多区域集群环境,这意味着数据卷能够在满足你的 Pod 运行需要的合适的区域被供应,从而允许您跨故障域轻松部署和扩展有状态工作负载,从而提供高可用性和容错能力。 + + +## 以前的挑战 + + +在此功能被提供之前,在多区域集群中使用区域化的持久磁盘(例如 AWS ElasticBlockStore,Azure Disk,GCE PersistentDisk)运行有状态工作负载存在许多挑战。动态供应独立于 Pod 调度处理,这意味着只要您创建了一个 PersistentVolumeClaim(PVC),一个卷就会被供应。这也意味着供应者不知道哪些 Pod 正在使用该卷,也不清楚任何可能影响调度的 Pod 约束。 + + +这导致了不可调度的 Pod,因为在以下区域中配置了卷: + + +* 没有足够的 CPU 或内存资源来运行 Pod +* 与节点选择器、Pod 亲和或反亲和策略冲突 +* 由于污点(taint)不能运行 Pod + + +另一个常见问题是,使用多个持久卷的非有状态 Pod 可能会在不同的区域中配置每个卷,从而导致一个不可调度的 Pod。 + + +次优的解决方法包括节点超配,或在正确的区域中手动创建卷,但这会造成难以动态部署和扩展有状态工作负载的问题。 + + +拓扑感知动态供应功能解决了上述所有问题。 + + +## 支持的卷类型 + + +在 1.12 中,以下驱动程序支持拓扑感知动态供应: + + +* AWS EBS +* Azure Disk +* GCE PD (包括 Regional PD) +* CSI(alpha) - 目前只有 GCE PD CSI 驱动实现了拓扑支持 + + +## 设计原则 + + +虽然最初支持的插件集都是基于区域的,但我们设计此功能时遵循 Kubernetes 跨环境可移植性的原则。 +拓扑规范是通用的,并使用类似于基于标签的规范,如 Pod nodeSelectors 和 nodeAffinity。 +该机制允许您定义自己的拓扑边界,例如内部部署集群中的机架,而无需修改调度程序以了解这些自定义拓扑。 + + +此外,拓扑信息是从 Pod 规范中抽象出来的,因此 Pod 不需要了解底层存储系统的拓扑特征。 +这意味着您可以在多个集群、环境和存储系统中使用相同的 Pod 规范。 + + +## 入门 + + +要启用此功能,您需要做的就是创建一个将 `volumeBindingMode` 设置为 `WaitForFirstConsumer` 的 StorageClass: + +``` +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: topology-aware-standard +provisioner: kubernetes.io/gce-pd +volumeBindingMode: WaitForFirstConsumer +parameters: + type: pd-standard +``` + + +这个新设置表明卷配置器不立即创建卷,而是等待使用关联的 PVC 的 Pod 通过调度运行。 +请注意,不再需要指定以前的 StorageClass `zone` 和 `zones` 参数,因为现在在哪个区域中配置卷由 Pod 策略决定。 + + +接下来,使用此 StorageClass 创建一个 Pod 和 PVC。 +此过程与之前相同,但在 PVC 中指定了不同的 StorageClass。 +以下是一个假设示例,通过指定许多 Pod 约束和调度策略来演示新功能特性: + + +* 一个 Pod 多个 PVC +* 跨子区域的节点亲和 +* 同一区域 Pod 反亲和 + +``` +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: web +spec: + serviceName: "nginx" + replicas: 2 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-central1-a + - us-central1-f + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - nginx + topologyKey: failure-domain.beta.kubernetes.io/zone + 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 + - name: logs + mountPath: /logs + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: topology-aware-standard + resources: + requests: + storage: 10Gi + - metadata: + name: logs + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: topology-aware-standard + resources: + requests: + storage: 1Gi +``` + + +之后,您可以看到根据 Pod 设置的策略在区域中配置卷: + +``` +$ kubectl get pv -o=jsonpath='{range .items[*]}{.spec.claimRef.name}{"\t"}{.metadata.labels.failure\-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}' +www-web-0 us-central1-f +logs-web-0 us-central1-f +www-web-1 us-central1-a +logs-web-1 us-central1-a +``` + + +## 我怎样才能了解更多? + + +有关拓扑感知动态供应功能的官方文档可在此处获取:https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode + + +有关 CSI 驱动程序的文档,请访问:https://kubernetes-csi.github.io/docs/ + + +## 下一步是什么? + + +我们正积极致力于改进此功能以支持: + + +* 更多卷类型,包括本地卷的动态供应 +* 动态容量可附加计数和每个节点的容量限制 + + +## 我如何参与? + + +如果您对此功能有反馈意见或有兴趣参与设计和开发,请加入 [Kubernetes 存储特别兴趣小组](https://github.com/kubernetes/community/tree/master/sig-storage)(SIG)。我们正在快速成长,并始终欢迎新的贡献者。 + + +特别感谢帮助推出此功能的所有贡献者,包括 Cheng Xing ([verult](https://github.com/verult))、Chuqiang Li ([lichuqiang](https://github.com/lichuqiang))、David Zhu ([davidz627](https://github.com/davidz627))、Deep Debroy ([ddebroy](https://github.com/ddebroy))、Jan Šafránek ([jsafrane](https://github.com/jsafrane))、Jordan Liggitt ([liggitt](https://github.com/liggitt))、Michelle Au ([msau42](https://github.com/msau42))、Pengfei Ni ([feiskyer](https://github.com/feiskyer))、Saad Ali ([saad-ali](https://github.com/saad-ali))、Tim Hockin ([thockin](https://github.com/thockin)),以及 Yecheng Fu ([cofyc](https://github.com/cofyc))。 diff --git a/content/zh/blog/_posts/2018-10-15-steering-election-results.md b/content/zh/blog/_posts/2018-10-15-steering-election-results.md new file mode 100644 index 0000000000000..8e7d5edf7e569 --- /dev/null +++ b/content/zh/blog/_posts/2018-10-15-steering-election-results.md @@ -0,0 +1,73 @@ +--- +layout: blog +title: '2018 年督导委员会选举结果' +date: 2018-10-15 +--- + + + +**作者**: Jorge Castro (Heptio), Ihor Dvoretskyi (CNCF), Paris Pittman (Google) + + +## 结果 + +[Kubernetes 督导委员会选举](https://kubernetes.io/blog/2018/09/06/2018-steering-committee-election-cycle-kicks-off/)现已完成,以下候选人获得了立即开始的两年任期: + +* Aaron Crickenberger, Google, [@spiffxp](https://github.com/spiffxp) +* Davanum Srinivas, Huawei, [@dims](https://github.com/dims) +* Tim St. Clair, Heptio, [@timothysc](https://github.com/timothysc) + + +## 十分感谢! + + +* 督导委员会荣誉退休成员 [Quinton Hoole](https://github.com/quinton-hoole),表扬他在过去一年为社区所作的贡献。我们期待着 +* 参加竞选的候选人。愿我们永远拥有一群强大的人,他们希望在每一次选举中都能像你们一样推动社区向前发展。 +* 共计 307 名选民参与投票。 +* 本次选举由康奈尔大学主办 [CIVS](https://civs.cs.cornell.edu/)! + + +## 加入督导委员会 + +你可以关注督导委员会的[任务清单](https://git.k8s.io/steering/backlog.md),并通过向他们的[代码仓库](https://github.com/kubernetes/steering)提交 issue 或 PR 的方式来参与。他们也会在[UTC 时间每周三晚 8 点](https://github.com/kubernetes/steering)举行会议,并定期与我们的贡献者见面。 + + +督导委员会会议: + +* [YouTube 播放列表](https://www.youtube.com/playlist?list=PL69nYSiGNLP1yP1B_nd9-drjoxp0Q14qM) + + +与我们的贡献者会面: + + + +* [2018 年 10 月 3 日](https://youtu.be/x6Jm8p0K-IQ) +* [2018 年 7 月 5 日](https://youtu.be/UbxWV12Or58) diff --git a/content/zh/blog/_posts/2018-10-16-kubernetes-2018-north-american-contributor-summit.md b/content/zh/blog/_posts/2018-10-16-kubernetes-2018-north-american-contributor-summit.md new file mode 100644 index 0000000000000..b504a5c6b6082 --- /dev/null +++ b/content/zh/blog/_posts/2018-10-16-kubernetes-2018-north-american-contributor-summit.md @@ -0,0 +1,118 @@ +--- +layout: "Blog" +title: "Kubernetes 2018 年北美贡献者峰会" +date: 2018-10-16 +--- + + +**作者:** + +[Bob Killen][bob](密歇根大学) +[Sahdev Zala][sahdev](IBM), +[Ihor Dvoretskyi][ihor](CNCF) + + +2018 年北美 Kubernetes 贡献者峰会将在西雅图 [KubeCon + CloudNativeCon][kubecon] 会议之前举办,这将是迄今为止规模最大的一次盛会。 + +这是一个将新老贡献者聚集在一起,面对面交流和分享的活动;并为现有的贡献者提供一个机会,帮助塑造社区发展的未来。它为新的社区成员提供了一个学习、探索和实践贡献工作流程的良好空间。 + + +与之前的贡献者峰会不同,本次活动为期两天,有一个更为轻松的行程安排,一般贡献者将于 12 月 9 日(周日)下午 5 点至 8 点在距离会议中心仅几步远的 [Garage Lounge and Gaming Hall][garage] 举办峰会。在那里,贡献者也可以进行台球、保龄球等娱乐活动,而且还有各种食品和饮料。 + + +接下来的一天,也就是 10 号星期一,有三个独立的会议你可以选择参与: + + +### 新贡献者研讨会: + +为期半天的研讨会旨在让新贡献者加入社区,并营造一个良好的 Kubernetes 社区工作环境。 +请在开会期间保持在场,该讨论会不允许随意进出。 + + +### 当前贡献者追踪: + +保留给那些积极参与项目开发的贡献者;目前的贡献者追踪包括讲座、研讨会、聚会、Unconferences 会议、指导委员会会议等等! +请留意 [GitHub 中的时间表][时间表],因为内容经常更新。 + + +### Docs 冲刺: + +SIG-Docs 将在活动日期临近的时候列出一个需要处理的问题和挑战列表。 + + +## 注册: + +要注册贡献者峰会,请参阅 Git Hub 上的[活动详情注册部分][注册]。请注意报名正在审核中。 +如果您选择了 “当前贡献者追踪”,而您却不是一个活跃的贡献者,您将被要求参加新贡献者研讨会,或者被要求进入候补名单。 +成千上万的贡献者只有 300 个位置,我们需要确保正确的人被安排席位。 + + +如果您有任何问题或疑虑,请随时通过 community@kubernetes.io 联系贡献者峰会组织团队。 + + +期待在那里看到每个人! + +[bob]: https://twitter.com/mrbobbytables +[sahdev]: https://twitter.com/sp_zala +[ihor]: https://twitter.com/idvoretskyi +[kubecon]: https://events.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2018/ +[garage]: https://www.garagebilliards.com/ +[时间表]: https://git.k8s.io/community/events/2018/12-contributor-summit#agenda +[注册]: https://git.k8s.io/community/events/2018/12-contributor-summit#registration diff --git a/content/zh/blog/_posts/2018-11-08-kubernetes-docs-update-i18n.md b/content/zh/blog/_posts/2018-11-08-kubernetes-docs-update-i18n.md new file mode 100644 index 0000000000000..cf6d5e58cbd64 --- /dev/null +++ b/content/zh/blog/_posts/2018-11-08-kubernetes-docs-update-i18n.md @@ -0,0 +1,89 @@ +--- +layout: blog +title: 'Kubernetes 文档更新,国际版' +date: 2018-11-08 +--- + + + +**作者**:Zach Corleissen (Linux 基金会) + + +作为文档特别兴趣小组(SIG Docs)的联合主席,我很高兴能与大家分享 Kubernetes 文档在本地化(l10n)方面所拥有的一个完全成熟的工作流。 + + +## 丰富的缩写 + + +L10n 是 _localization_ 的缩写。 + + +I18n 是 _internationalization_ 的缩写。 + + +I18n 定义了[做什么](https://www.w3.org/International/questions/qa-i18n) 能让 l10n 更容易。而 L10n 更全面,相比翻译( _t9n_ )具备更完善的流程。 + + +## 为什么本地化很重要 + + +SIG Docs 的目标是让 Kubernetes 更容易为尽可能多的人使用。 + + +一年前,我们研究了是否有可能由一个独立翻译 Kubernetes 文档的中国团队来主持文档输出。经过多次交谈(包括 OpenStack l10n 的专家),[多次转变](https://kubernetes.io/blog/2018/05/05/hugo-migration/),以及[重新致力于更轻松的本地化](https://github.com/kubernetes/website/pull/10485),我们意识到,开源文档就像开源软件一样,是在可能的边缘不断进行实践。 + + +整合工作流程、语言标签和团队级所有权可能看起来像是十分简单的改进,但是这些功能使 l10n 可以扩展到规模越来越大的 l10n 团队。随着 SIG Docs 不断改进,我们已经在单一工作流程中偿还了大量技术债务并简化了 l10n。这对未来和现在都很有益。 + + +## 整合的工作流程 + + +现在,本地化已整合到 [kubernetes/website](https://github.com/kubernetes/website) 存储库。我们已经配置了 Kubernetes CI/CD 系统,[Prow](https://github.com/kubernetes/test-infra/tree/master/prow) 来处理自动语言标签分配以及团队级 PR 审查和批准。 + + +### 语言标签 + + +Prow 根据文件路径自动添加语言标签。感谢 SIG Docs 贡献者 [June Yi](https://github.com/kubernetes/test-infra/pull/9835),他让人们还可以在 pull request(PR)注释中手动分配语言标签。例如,当为 issue 或 PR 留下下述注释时,将为之分配标签 `language/ko`(Korean)。 + +``` +/language ko +``` + + + +这些存储库标签允许审阅者按语言过滤 PR 和 issue。例如,您现在可以过滤 kubernetes/website 面板中[具有中文内容的 PR](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+label%3Alanguage%2Fzh)。 + + +### 团队审核 + + +L10n 团队现在可以审查和批准他们自己的 PR。例如,英语的审核和批准权限在位于用于显示英语内容的顶级子文件夹中的 [OWNERS 文件中指定](https://github.com/kubernetes/website/blob/master/content/en/OWNERS)。 + + +将 `OWNERS` 文件添加到子目录可以让本地化团队审查和批准更改,而无需由可能并不擅长该门语言的审阅者进行批准。 + + +## 下一步是什么 + + +我们期待着[上海的 doc sprint](https://kccncchina2018english.sched.com/event/HVb2/contributor-summit-doc-sprint-additional-registration-required) 能作为中国 l10n 团队的资源。 + + +我们很高兴继续支持正在取得良好进展的日本和韩国 l10n 队伍。 + + +如果您有兴趣将 Kubernetes 本地化为您自己的语言或地区,请查看我们的[本地化 Kubernetes 文档指南](https://kubernetes.io/docs/contribute/localization/),并联系 [SIG Docs 主席团](https://github.com/kubernetes/community/tree/master/sig-docs#leadership)获取支持。 + + +### 加入SIG Docs + + +如果您对 Kubernetes 文档感兴趣,请参加 SIG Docs [每周会议](https://github.com/kubernetes/community/tree/master/sig-docs#meetings),或在 [Kubernetes Slack 加入 #sig-docs](https://kubernetes.slack.com/messages/C1J0BPD2M/details/)。 diff --git a/content/zh/blog/_posts/2018-12-05-new-contributor-shanghai.md b/content/zh/blog/_posts/2018-12-05-new-contributor-shanghai.md index 4ad2391ace85d..bf57259f549bd 100644 --- a/content/zh/blog/_posts/2018-12-05-new-contributor-shanghai.md +++ b/content/zh/blog/_posts/2018-12-05-new-contributor-shanghai.md @@ -3,7 +3,7 @@ layout: blog title: '新贡献者工作坊上海站' date: 2018-12-05 --- - + +--- +title: 案例分析 +linkTitle: 案例分析 +bigheader: Kubernetes 用户案例分析 +abstract: 在生产环境下使用 Kubernetes 的案例集 +layout: basic +class: gridPage +cid: caseStudies +--- + + diff --git a/content/zh/case-studies/buffer/buffer_featured.png b/content/zh/case-studies/buffer/buffer_featured.png new file mode 100644 index 0000000000000..cd6aaba4ca6a0 Binary files /dev/null and b/content/zh/case-studies/buffer/buffer_featured.png differ diff --git a/content/zh/case-studies/buffer/buffer_logo.png b/content/zh/case-studies/buffer/buffer_logo.png new file mode 100644 index 0000000000000..1b4b3b7e525d0 Binary files /dev/null and b/content/zh/case-studies/buffer/buffer_logo.png differ diff --git a/content/zh/case-studies/buffer/index.html b/content/zh/case-studies/buffer/index.html new file mode 100644 index 0000000000000..58bb793dea573 --- /dev/null +++ b/content/zh/case-studies/buffer/index.html @@ -0,0 +1,157 @@ +--- +title: 案例研究:Buffer + +case_study_styles: true +cid: caseStudies +css: /css/style_buffer.css +--- + + +
+

案例研究:
+
使小型分布式团队轻松部署
+

+
+ + +
+ 公司 Buffer     位置  全球     行业  社交媒体技术公司 +
+ +
+ +
+
+
+ + +

挑战

+ Buffer 拥有一支80人的分布式团队,他们遍布全球近十几个时区。这样一个为代理商和营销人员提供社交媒体管理的公司,希望解决其“典型的单一庞大编码基数问题”,架构师 Dan Farrelly 这样说。“我们希望拥有一种流动性的基础架构,开发人员可以创建一个应用程序,可以根据需要部署并横向扩展它”。 +
+ +
+ +

解决方案

+拥抱容器化,Buffer 将其基础设施从 AWS 上的 Elastic Beanstalk 迁移到由 Kubernetes 负责编排的 Docker 上。 +
+
+ +

影响

+Farrelly 说,新系统“提高了我们将新变化进行部署和上线的能力”。“在自己的计算机上构建一些东西,并且知道它是可用的,这已经让事情简单了很多;而且我们的反馈周期现在也快了很多。” +
+
+
+ +
+
+ +“我们的团队能够直接使用既有的 Kubernetes 解决方案,这太棒了,而且它还在不断改进中。在意识到我们需要某些功能之前,它就出现在下一个版本中,或者在未来几个月内出现。

- DAN FARRELLY, BUFFER ARCHITECT +
+
+ +
+
+ +

Dan Farrelly 用木工类比来解释他的公司 Buffer ,随着过去几年的发展,公司开始有这个问题。

+ + +“如果你自己做一张桌子,这很好!”公司的架构师说。“如果你请另一个人一起来做这个桌子,也许这个人可以在你抛光桌面时开始对腿进行抛光。但是,当你把第三个或第四个人带进来时,有人也许应该在另外一张桌子上工作。”需要处理越来越多不同的桌子,使 Buffer 走上了 Kubernetes 实现微服务和容器化的道路。 +

+ +自2012年左右以来,Buffer 开始使用 Elastic Beanstalk ,这是亚马逊网络服务提供的网络基础设施编排服务。“我们部署了一个单一的PHP应用程序,它是在五六个环境中相同的应用程序,”Farrelly 说。“我们在很大程度上是一家产品驱动型的公司。” + +这一切都是为了尽快给应用推出新功能并进行交付,如果能够正常运行,我们就不会花太多时间在上面。如果产品变得有点慢,我们可能会使用更快的服务器或只是增加一个实例,这些就已经足够了。然后继续前进。 +

+ +但事情在2016年就到了头。随着应用提交修改的数量不断增加,Farrelly 和 Buffer 当时的首席技术官 Sunil Sadasivan 决定,是重新思考和构建其基础架构的时候了。“这是一个典型的单一庞大编码基数问题,”Farrelly说。公司的一些团队已经在开发环境中成功使用Docker,但在生产环境中,运行在 Docker 上的唯一应用程序是一个看不到真实用户流量的营销网站。他们希望在使用 Docker 上更进一步,下一步是寻找业务流程的选项。 +
+
+ +
+
+ +Kubernetes 所做的所有事情都很好地适应了 Buffer 的需求。Farrelly 说:“我们希望拥有一种流动基础架构,开发人员可以创建一个应用程序,并在必要时部署并进行水平扩展。”“我们很快就使用一些脚本来设置几个测试集群,在容器中构建了一些小的概念性验证应用程序,并在一小时内部署了这些内容。我们在生产中运行容器方面经验很少。令人惊奇的是,我们能很快地用 Kubernetes 来处理。” +
+
+ +
+
+ +首先,他们考虑了MesosphereDC/OSAmazon Elastic Container Service(他们的数据系统团队已经将其用于某些数据管道作业)。虽然他们对这些产品印象深刻,但他们最终还是与 Kubernetes 合作。 + +Farrelly 说:“我们的应用仍在 AWS 上运行,但是我们的团队通过 Kubernetes 无需手动配置即可创建服务并按需创建负载均衡器,这是使用 Kubernetes 的最佳入门体验。”“我们不需要考虑如何配置这个或那个,特别是相较于以前的 Elastic Beanstalk 环境,它为我们提供了一个自动配置的负载均衡器。我真的很喜欢 Kubernetes 对命令行的控制,只需要对端口进行配置,这样更加灵活。Kubernetes 是为做它所做的事情而设计的,所以它做得非常好。” +

+ +Kubernetes 所做的所有事情都很好地适应了 Buffer 的需求。Farrelly 说:“我们希望拥有一种流动基础架构,开发人员可以创建一个应用程序,并在必要时部署并进行水平扩展。”“我们很快就使用一些脚本来设置几个测试集群,在容器中构建了一些小的概念性验证应用程序,并在一小时内部署了这些内容。我们在生产中运行容器方面经验很少。令人惊奇的是,我们能很快地用 Kubernetes 来处理。” +

+ +最重要的是,它为公司最显著的特征之一提供了强大的解决方案:他们的远程团队分布在十几个不同的时区。Farrelly 说:“对我们的基础设施有深入了解的人生活在不同于我们相对集中的时区,而我们的大部分产品工程师都住在其他地方。”“因此,我们确实希望有人能够尽早掌握这套系统并利用好它,而不必担心部署工程师正在睡觉。否则,人们会为了一些东西必须得等待12到24小时左右。看到人们前进得更快,这真的很酷。” +

+ +Farrelly 说,Buffer 拥有相对较小的工程团队,只有 25 人,只有少数人从事基础设施工作,大多数前端开发人员都需要“一些强大的配置能力,以便部署任何他们想要的内容。”以前,“只有几个人知道如何用旧的方式设置一切。有了这个系统,审查文档变得很容易,并且能很快地看到效果。它降低了我们获取在开发环境中所需要一切的门槛。因为我们团队的人数不足以来构建所有这些工具或像其他大公司那样管理基础架构。” +
+
+ +
+
+ +Farrelly 说:“在我们以往的工作方式中,反馈循环流程要长得多,而且很微妙,因为如果你部署了某些东西,就存在破坏其他东西的风险。”“我们通过围绕 Kubernetes 构建的部署类型,能够及时检测 Bug 并修复它们,并使其部署得超快。这一秒正在修复漏洞,不一会就上线运行了。” +
+
+ +
+
+ +为了帮助解决这一问题,Buffer 开发人员编写了一个部署机器人,该机器人包装了 Kubernetes 部署过程,并且每个团队都可以使用。”“以前,我们的数据分析师会更新 Python 分析脚本,并且必须等待该团队的主管单击该按钮并部署它,”Farrelly 解释道。“现在,我们的数据分析师可以进行更改,输入 Slack 命令,‘/deploy’,它会立即进行部署。他们不需要等待这些缓慢的周转时间,他们甚至不知道它在哪里运行。这些都不重要了。 +

+ +团队使用 Kubernetes 从头开始构建的第一个应用程序是一种新的图像大小调整服务。作为一种社交媒体管理工具,它允许营销团队通过发帖进行协作,并通过多个社交媒体配置文件和网络发送更新,Buffer 必须能够根据需要调整照片的大小,以满足不同的社交网络。Farrelly 说:“我们一直有这些拼凑在一起的解决方案。” +

+ +为了创建这项新服务,一位高级产品工程师被指派学习 Docker 和 Kubernetes,然后构建服务、测试、部署和监视服务,他能够相对快速地完成该服务。Farrelly说:“在我们以往的工作方式中,反馈循环流程要长得多,而且很微妙,因为如果你部署了某些东西,就存在破坏其他东西的风险。”“我们通过围绕 Kubernetes 构建的部署类型,能够及时检测 Bug 并修复它们,并使其部署得超快。这一秒正在修复漏洞,不一会就上线运行了。” +

+ +此外,与旧系统不同,他们只需一个命令就可以水平缩放内容。“当我们推出它,”Farrelly说,“我们可以预测,只需点击一个按钮。这使我们能够处理用户对系统的需求,并轻松扩展以处理它。” +

+ +他们以前不能做的另外一件事是金丝雀部署。Farrelly说,这种新功能“使我们在部署重大变革方面更加自信。”“以前,虽然进行很多测试但仍表现不错,但它也存在很多‘手指交叉’。这是每天运行 800000 次的东西,这是我们业务的核心。如果它不工作,我们的业务也无法运行。在 Kubernetes 世界中,我可以执行金丝雀部署以测试 1%,如果它不工作,我可以很快将其关闭。这使我们在快速部署和推出新更改的同时降低风险的能力得到了提高。” + +
+
+ +
+
+ +Farrelly 说:“如果你想在生产中运行容器,拥有像谷歌内部使用的那种效果,那么 Kubernetes 就是一个很好的方法。”“我们是一个相对较小的团,实际上运行 Kubernetes,我们之前从来没来做过这样的事情。因此,它比你想象的更容易上手,这正是我想要告诉正在尝试使用它的人们的一件很重要的事。挑几个应用,把它们准备好,在机器上运行几个月,看看它能处理的怎么样。通过这种方式你可以学到很多东西。” +
+
+ +
+
+ +到 2016 年 10 月,Buffer 54% 的流量都通过其 Kubernetes 集群。Farrelly 说:“我们很多传统功能仍然运行正常,这些部分可能会转移到 Kubernetes 或永远留在我们的旧设置中。”但该公司当时承诺,“所有新的开发,所有新功能,将在Kubernetes上运行。” +

+ +2017年计划是将所有旧应用程序迁移到新的 Kubernetes 集群,并运行他们从旧基础架构中撤出的所有内容,以及他们正在另一个 Kubernetes 集群上开发的新服务。Farrelly 说:“我想为团队中的每个人带来我们早期服务的所有好处。” +

+

+ +对于 Buffer 的工程师来说,这是一个令人兴奋的过程。“每次部署新服务时,我们都需要弄清楚:好的,体系结构是什么?这些服务如何沟通?构建此服务的最佳方式是什么?”Farrelly说。“然后,我们使用 Kubernetes 的特性将所有部分聚合到一起。在学习如何设计面向服务的体系结构时,它使我们能够进行试验。以前,我们只是不能做到这一点。这实际上给了我们一个空白的白板,所以我们可以做任何我们想要的。” +

+ +部分空白是 Kubernetes 提供的灵活性,如果某一天 Buffer 可能想要或需要改变他的云服务。“这是与云无关的,所以也许有一天我们可以切换到谷歌或其他地方,”Farrelly 说。“我们非常依赖亚马逊的基础服务,但很高兴知道,如果我们需要的话,我们可以搬走。” +

+ +此时,Buffer 团队无法想象以任何其他方式运行其基础结构,他们很乐意传播这一信息。Farrelly 说:“如果你想在生产中运行容器,拥有像谷歌内部使用的那种效果,那么 Kubernetes 就是一个很好的方法。”“我们是一个相对较小的团队,实际上运行 Kubernetes,我们之前从来没来做过这样的事情。因此,它比你想象的更容易上手,这正是我想要告诉正在尝试使用它的人们的一件很重要的事。挑几个应用,把它们准备好,在机器上运行几个月,看看它能处理的怎么样。通过这种方式你可以学到很多东西。” +

+
+
diff --git a/content/zh/case-studies/ccp-games/ccp_logo.png b/content/zh/case-studies/ccp-games/ccp_logo.png new file mode 100644 index 0000000000000..cbf3d267ba8dd Binary files /dev/null and b/content/zh/case-studies/ccp-games/ccp_logo.png differ diff --git a/content/zh/case-studies/ccp-games/index.html b/content/zh/case-studies/ccp-games/index.html new file mode 100644 index 0000000000000..8867cbb323442 --- /dev/null +++ b/content/zh/case-studies/ccp-games/index.html @@ -0,0 +1,4 @@ +--- +title: CCP Games +content_url: https://cloud.google.com/customers/ccp-games/ +--- \ No newline at end of file diff --git a/content/zh/case-studies/goldman-sachs/gs_logo.png b/content/zh/case-studies/goldman-sachs/gs_logo.png new file mode 100644 index 0000000000000..5cc8c14566ae5 Binary files /dev/null and b/content/zh/case-studies/goldman-sachs/gs_logo.png differ diff --git a/content/zh/case-studies/goldman-sachs/index.html b/content/zh/case-studies/goldman-sachs/index.html new file mode 100644 index 0000000000000..93d3022d12440 --- /dev/null +++ b/content/zh/case-studies/goldman-sachs/index.html @@ -0,0 +1,4 @@ +--- +title: Goldman Sachs +content_url: http://blogs.wsj.com/cio/2016/02/24/big-changes-in-goldmans-software-emerge-from-small-containers/ +--- \ No newline at end of file diff --git a/content/zh/case-studies/huawei/huawei_featured.png b/content/zh/case-studies/huawei/huawei_featured.png new file mode 100644 index 0000000000000..22071b4691e38 Binary files /dev/null and b/content/zh/case-studies/huawei/huawei_featured.png differ diff --git a/content/zh/case-studies/huawei/huawei_logo.png b/content/zh/case-studies/huawei/huawei_logo.png new file mode 100644 index 0000000000000..94361a27eb5af Binary files /dev/null and b/content/zh/case-studies/huawei/huawei_logo.png differ diff --git a/content/zh/case-studies/huawei/index.html b/content/zh/case-studies/huawei/index.html new file mode 100644 index 0000000000000..cfd2f562b6711 --- /dev/null +++ b/content/zh/case-studies/huawei/index.html @@ -0,0 +1,433 @@ +--- +title: 华为案例分析 + +case_study_styles: true +cid: caseStudies +css: /css/style_huawei.css +--- + + + +
+

案例分析:
以用户和供应商身份拥抱云原生

+ +
+ +
+ 公司  华为     地点  中国深圳     产业  通信设备 + +
+ +
+ +
+ +
+
+

挑战

+ + 华为是世界上最大的电信设备制造商,拥有超过 18 万名员工。 + + + 为了支持华为在全球的快速业务发展,华为内部 IT 部门有 8 个数据中心, + 这些数据中心在 100K+ VMs 上运行了 800 多个应用程序,服务于这 18 万用户。 + + + 随着新应用程序的快速增长,基于 VM 的应用程序的管理和部署的成本和效率都成为业务敏捷性的关键挑战。 + + + 该公司首席软件架构师、开源社区总监侯培新表示: + “这是一个超大的分布式系统,因此我们发现,以更一致的方式管理所有任务始终是一个挑战。 + 我们希望进入一种更敏捷、更得体的实践”。 + + +
+ +
+

解决方案

+ + 在决定使用容器技术后,华为开始将内部 IT 部门的应用程序迁移到 Kubernetes 上运行。 + 到目前为止,大约 30% 的应用程序已经转移为云原生程序。 + +
+
+

影响

+ + “到 2016 年底,华为的内部 IT 部门使用基于 Kubernetes 的平台即服务(PaaS)解决方案管理了 4000 多个节点和数万个容器。 + 全局部署周期从一周缩短到几分钟,应用程序交付效率提高了 10 倍”。 + + + 对于底线,侯培新表示,“我们还看到运营开支大幅削减,在某些情况下可削减 20% 到 30%,我们认为这对我们的业务非常有帮助”。 + + + 这里给出一些华为内部结果资料、外部需求,也是公司的技术包装产品 FusionStage™ , + 它被作为一套 PaaS 解决方案提供给其客户。 + +
+ +
+ +
+ +
+
+ “如果你是一个供应商,为了说服你的客户,你应该自己使用它。 + 幸运的是,因为华为有很多员工,我们可以利用这种技术来展示我们所能构建的云的规模。” + + +
+ +
- 侯培新,首席软件架构师、开源社区总监 + +
+
+
+ +
+ +
+ 华为的 Kubernetes 之旅始于一位开发者。 + + + 两年前,这家网络和电信巨头雇佣的一名工程师对 Kubernetes + 这一跨主机集群的管理应用程序容器的技术产生了兴趣,并开始为其开源社区作出贡献。 + + + 随着技术和社区的发展,他不断地将这门技术告诉他的经理们。

+ + + 与此同时,华为也在为其内部的企业 IT 部门寻找更好的编排系统,该系统应该支持每一个业务的流程处理。 + + + 华为首席软件架构师、开源社区总监侯培新表示, + “我们在全球拥有逾 18 万名员工,内部流程复杂,所以这个部门可能每周都需要开发一些新的应用程序。 + + + 我们的 IT 部门经常需要启动数万个容器,任务要跨越全球数千个节点。 + 这是一个超大的分布式的系统,所以我们发现以更一致的方式管理所有的任务总是一个挑战”。

+ + + 过去,华为曾使用虚拟机来封装应用程序,但是,“每次我们启动虚拟机时”,侯培新说, + “无论是因为它是一项新服务,还是因为它是一项由于节点功能异常而被关闭的服务,都需要花费大量时间”。 + + + 华为转向了容器化,所以是时候尝试 Kubernetes 了。 + 采纳了这位工程师的建议花费了一年的时间,这个过程“不是一蹴而就的”,侯说, + + + 但一旦投入使用,“Kubernetes 基本上解决了我们的大部分问题。 + 以前,部署时间大约需要一周,现在只需几分钟。 + + + 开发人员非常高兴。使用 Kubernetes 的那个部门也十分高兴”。

+ + + 侯培新看到了使用这项技术给公司带来的巨大好处, + “Kubernetes 为基于云的应用程序带来了敏捷性、扩展能力和 DevOps 实践”,他说, + + + “它为我们提供了自定义调度体系结构的能力,这使得容器任务之间的关联性成为可能,从而提高了效率。 + 它支持多种容器格式,同时广泛支持各种容器网络解决方案和容器存储方案”。 + +
+
+ +
+
+ “Kubernetes 基本上解决了我们的大部分问题。 + 以前,部署时间大约需要一周,现在只需几分钟。 + 开发人员很高兴。使用 Kubernetes 的部门也很高兴。” + +
+
+ +
+
+ 最重要的是,这对底线有影响。侯培新说, + “我们还看到,在某些情况下,运营开支会大幅削减 20% 到 30%,这对我们的业务非常有帮助”。

+ + + 华为对这些初步结果感到满意,并看到客户对云原生技术的需求,因此加大了 Kubernetes 的投入。 + 2016 年春,公司不仅成为用户,而且成为了供应商。

+ + + “我们构建了 Kubernetes 技术解决方案”,侯培新说, + 指的是华为的 FusionStage™ PaaS 输出。 + + + “我们的客户,从非常大的电信运营商到银行,都喜欢云原生的想法。他们喜欢 Kubernetes 的技术。 + 但是他们需要花费大量的时间来分解他们的应用程序,将它们转换为微服务体系结构。 + 作为解决方案提供者,我们帮助他们。 + + + 我们已经开始与一些中国银行合作,我们看到中国移动(China Mobile)和德国电信(Deutsche Telekom)等客户对我们很感兴趣”。

+ + + “如果你是一个用户,你就仅仅是个用户”,侯培新补充道,“但如果你是一个供应商,为了说服你的客户,你应该自己使用它。 + + + 幸运的是,因为华为有很多员工,我们可以利用这种技术来展示我们所能构建的云的规模,向客户提供智慧服务”。 + + + 尽管华为拥有自己的私有云,但其许多客户使用华为的解决方案运行跨云应用程序。 + 这是一个很大的卖点,大多数公共云提供商现在都支持 Kubernetes。 + 侯培新说,“这使得跨云转换比其他解决方案更容易”。

+ +
+
+ +
+
+ “我们的客户,从非常大的电信运营商到银行,都喜欢云原生的想法。他们喜欢 Kubernetes 的技术。 + 但是他们需要花很多时间来分解他们的应用程序,把它们变成微服务体系结构,作为一个解决方案提供商,我们帮助他们。” + +
+
+ +
+
+ + 在华为内部,一旦他的团队完成内部业务流程部门向 Kubernetes 的转型,侯培新希望说服更多部门转向云原生开发和实践。 + + + “我们有很多软件开发人员,所以我们将为他们提供我们的平台作为服务解决方案,我们自己的产品”, + 他说,“我们希望在他们的迭代周期中看到显著的成本削减”。

+ + + 在见证了华为最开始的向 Kubernetes 的转型之后,侯培新为其他考虑该技术的公司提供了建议, + “当你开始设计应用程序的架构时,首先考虑云原生,然后再考虑微服务架构”,他说,“我想你会从中受益”。

+ + + 但是如果您已经有了遗留应用程序,“首先从这些应用程序中一些对微服务友好的部分开始, + 这些部分相对容易分解成更简单的部分,并且相对轻量级”,侯培新说, + + + “不要从一开始就认为我想在几天内将整个架构或所有东西都迁移到微服务中。 + 不要把它当作目标。你应该循序渐进地做这件事。 + 我想说的是,对于遗留应用程序,并不是每个部分都适合微服务架构”。

+ + + 毕竟,尽管侯培新对华为的 Kubernetes 充满热情,但他估计, + “未来 10 年,或许 80% 的工作负载可以分布式地在云原生环境中运行,但仍然有 20% 不是,但是没关系。 + 如果我们能够让 80% 的工作负载真正是云原生的、敏捷的,那么最终会有一个更好的世界”。 + +
+
+ +
+
+ “未来 10 年,可能 80% 的工作负载可以分布式地在云原生环境中运行,但仍然有 20% 不是,不过没关系。 + 如果我们能够让 80% 的工作负载真正是云原生的、敏捷的,那么最终会有一个更好的世界。” + +
+
+
+
+ 在不久的将来,侯培新期待着围绕着 Kubernetes 开发的新功能,尤其是华为正在开发的那些功能。 + + + 华为的工程师已经在为联邦功能(将多个 Kubernetes 集群放在一个框架中进行无缝管理)、调度、容器网络和存储,以及刚刚发布的一项名为 + Container Ops 的技术工作,这是一个 DevOps 管道引擎。 + + + “这将把每个 DevOps 作业放到一个容器中”,他解释说,“这种容器机制使用 Kubernetes 运行,也用于测试 Kubernetes。 + 有了这种机制,我们可以比以前更容易地创建、共享和管理容器化 DevOps 作业”。

+ + + 尽管如此,侯培新认为这项技术只是实现其全部潜力的一半。 + 首先,也是最重要的,他想要扩大它可以协调的规模, + 这对于华为这样的超大规模公司以及它的一些客户来说非常重要。

+ + + 侯培新自豪地指出,在华为第一位工程师成为 Kubernetes 的贡献者和传道者两年后,华为现在是这个社区的最大贡献者。 + 他说,“我们发现,你对社区的贡献越大,你得到的回报也就越多”。 + +
+
diff --git a/content/zh/case-studies/ibm/ibm_featured_logo.png b/content/zh/case-studies/ibm/ibm_featured_logo.png new file mode 100644 index 0000000000000..adb07a8cdf588 Binary files /dev/null and b/content/zh/case-studies/ibm/ibm_featured_logo.png differ diff --git a/content/zh/case-studies/ibm/ibm_featured_logo.svg b/content/zh/case-studies/ibm/ibm_featured_logo.svg new file mode 100644 index 0000000000000..577d8e97d960d --- /dev/null +++ b/content/zh/case-studies/ibm/ibm_featured_logo.svg @@ -0,0 +1 @@ +ibm_featured_logo \ No newline at end of file diff --git a/content/zh/case-studies/ibm/index.html b/content/zh/case-studies/ibm/index.html new file mode 100644 index 0000000000000..bb9a4a8943b65 --- /dev/null +++ b/content/zh/case-studies/ibm/index.html @@ -0,0 +1,93 @@ +--- +title: 案例研究:IBM + +case_study_styles: true +cid: caseStudies +css: /css/style_ibm.css +--- + + + +
+

案例研究:
在 Kubernetes 上使用 Notary 和 TUF 建立镜像信任服务

+ +
+ +
+ 公司  IBM     位置  阿蒙克, 纽约     行业  云计算 +
+ +
+
+
+
+

挑战

+ +IBM Cloud 提供公共、私有和混合云功能,包括基于 OpenWhisk 的服务 (FaaS)、托管于 Kubernetes 和容器,以及 Cloud Foundry 服务 (PaaS) 的各种运行时。这些运行时与公司企业技术(如 MQ 和 DB2、其现代人工智能 (AI) Watson 和数据分析服务)的强大功能相结合。IBM Cloud 用户可以使用其目录中 170 多个不同云原生服务的功能,包括 IBM 的气象公司 API 和数据服务等功能。在 2017 年后期,IBM 云容器托管团队希望构建镜像信任服务。

+

解决方案

+ +2018 年 2 月,这项新服务在 IBM 云中公开发布。IBM 云容器托管团队的软件开发者 Michael Hough 说,名为 Portieris 的镜像信任服务完全基于 Cloud Native Computing Foundation (CNCF) 的开源项目 Notary。Portieris 是 Kubernetes 的准入控制器,用于强制执行适当的信任等级。用户可以为每个 Kubernetes 命名空间或在集群级别创建镜像安全策略,并为不同的镜像强制实施不同级别的信任。Portieris 是 IBM 信任内容的关键部分,因为它使用户能够从 IKS 集群中使用公司的 Notary。产品是 Notary 服务器在 IBM 的云中运行,然后 Portieris 在 IKS 集群内运行。这使用户能够让 IKS 集群验证他们加载容器的镜像是否包含他们期望的内容,而 Portieris 是允许 IKS 集群应用该验证的原因。 + +
+
+

影响

+ +IBM 打算提供基于 Kubernetes 的容器服务和镜像托管服务,目的是为其企业客户提供完全安全的端到端平台。Hough 说:“镜像签名是该产品的关键部分之一,我们的容器托管团队将 Notary 视为在当前 Docker 和容器生态系统中实现该功能的实际方式。”该公司以前没有提供镜像签名,Notary 是它用来实现该功能的工具。“我们有一个多租户 Docker 托管服务,具有私有镜像托管功能,” Hough 说。“ Docker 托管使用哈希值来确保镜像内容正确,并且数据在传输和静态时都进行了加密。但它没有提供任何保证谁推镜像。我们使用 Notary 来允许用户在其专用注册表命名空间中签名镜像(如果他们愿意的话)。” +
+ +
+
+
+
+ + “我们将 CNCF 视为云原生开源的安全避难所,为成员项目(无论是原始供应商还是项目)提供稳定性、使用寿命和预期维护。”

- Michael Hough, IBM 容器托管团队软件开发人员 +
+
+
+
+ +

Docker 已经创建了 Notary 项目作为 The Update Framework (TUF) 的实现,TUF 的此实现为 Docker 内容信任提供了功能。

IBM 云容器托管团队的软件开发者 Michael Hough 说:“在 TUF 和 Notary 对 CNCF 做出了贡献后,我们发现它正在成为容器生态系统中镜像签名的实际标准。”

+ +选择 Notary 的关键原因是它已经与 IBM 的容器托管正在使用的现有身份验证技术兼容。TUF 的设计也是如此,它不要求托管团队必须涉足密钥管理业务。他说,这两项都是“有吸引力的设计决定,证实了我们对 Notary 的选择是正确的。”

+ +在 IBM Cloud 中引入 Notary 功能以实现镜像签名,可提高 IBM 云平台的安全性,“我们预计这将包括签署 IBM 官方镜像以及预期的有安全需求的企业客户,” Hough 说。与安全策略实现结合使用时,我们预计 CI/CD 管道中会更多地使用部署策略,以便根据镜像签名者对服务部署进行精细控制。 + +Hough 说,镜像签名的可用性“对于需要这种级别镜像来源和安全性的客户来说,是一个巨大的好处。”“借助我们的 IBM 云上的 Kubernetes 以及我们提供的许可控制器,它允许 IBM 服务以及 IBM 公共云的客户使用安全策略来控制服务部署。” +
+
+
+
+ + 镜像签名是我们 Kubernetes 容器服务的关键部分之一,我们的容器托管团队将 Notary 视为在当前 Docker 和容器生态系统中实现该功能的实际方式。

- Michael Hough, IBM 容器托管团队软件开发人员 + +
+
+
+
+ +现在,Notary 通常作为现有 IBM 云容器托管的一个组件在 IBM 的公共云中提供服务,因此它被部署为五个 IBM 云区域中的高可用服务。此高可用性部署在五个区域中的每个区域中各有三个实例,实现负载均衡与故障转移。Hough 说:“我们还将其部署到后端 IBM Cloudant 持久性存储服务,并随端到端 TLS 支持一起部署。”

+ +IBM 团队创建并开源了名为 Portieris 的 Kubernetes 准入控制器,该控制器使用 Notary 签名信息与客户定义的安全策略相结合,以控制将镜像部署到集群中。“我们希望通过使用我们的 Notary 服务来推动 Portieris 的使用,” Hough 说。

+ +IBM 在创建和支持开源基础(包括 CNCF)方面一直占据主导地位。IBM 开放技术副总裁 Todd Moore 是现任 CNCF 董事会主席,许多 IBM 员工活跃于 CNCF 成员项目中。 +
+
+
+
+ + “有新项目应对这些挑战,包括在 CNCF 内。我们一定会饶有兴趣地关注这些进步。我们发现 Notary 社区是一个积极友好的社区,对变化持开放态度,例如我们为持久存储添加的 CouchDB 后端。”

- Michael Hough, IBM 容器托管团队软件开发人员 +
+
+
+
+ +该公司已经使用的 CNCF 项目有 containerdEnvoyPrometheusgRPCCNI,而且正在探索 SPIFFESPIRE 在未来的潜在可用性。

+ +对于希望部署 Notary 或云原生基础架构的其他公司,Hough 有何建议?

+ +“虽然对于云原生基础结构软件的许多领域也是如此,但我们发现,高可用性、多区域的 Notary 部署需要扎实的实现来处理证书管理和轮换,”他说。“有新项目应对这些挑战,包括在 CNCF 内。我们一定会饶有兴趣地关注这些进步。我们发现 Notary 社区是一个积极友好的社区,对变化持开放态度,例如我们为持久存储添加的 CouchDB 后端。” +
+
diff --git a/content/zh/case-studies/liveperson/index.html b/content/zh/case-studies/liveperson/index.html new file mode 100644 index 0000000000000..0cadb0f274073 --- /dev/null +++ b/content/zh/case-studies/liveperson/index.html @@ -0,0 +1,4 @@ +--- +title: LivePerson +content_url: https://www.openstack.org/videos/video/running-kubernetes-on-openstack-at-liveperson +--- \ No newline at end of file diff --git a/content/zh/case-studies/liveperson/liveperson_logo.png b/content/zh/case-studies/liveperson/liveperson_logo.png new file mode 100644 index 0000000000000..b7e63d94f72d6 Binary files /dev/null and b/content/zh/case-studies/liveperson/liveperson_logo.png differ diff --git a/content/zh/case-studies/monzo/index.html b/content/zh/case-studies/monzo/index.html new file mode 100644 index 0000000000000..99d4f35934145 --- /dev/null +++ b/content/zh/case-studies/monzo/index.html @@ -0,0 +1,4 @@ +--- +title: Monzo +content_url: https://youtu.be/YkOY7DgXKyw +--- \ No newline at end of file diff --git a/content/zh/case-studies/monzo/monzo_logo.png b/content/zh/case-studies/monzo/monzo_logo.png new file mode 100644 index 0000000000000..854409d17eabb Binary files /dev/null and b/content/zh/case-studies/monzo/monzo_logo.png differ diff --git a/content/zh/case-studies/netease/index.html b/content/zh/case-studies/netease/index.html new file mode 100644 index 0000000000000..0ce8d133e2353 --- /dev/null +++ b/content/zh/case-studies/netease/index.html @@ -0,0 +1,105 @@ +--- +title: 案例研究:NetEase +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +--- + + + +
+

案例研究:
网易如何利用 Kubernetes 支持在全球的互联网业务

+ +
+ + +
+ 公司  网易     位置  杭州,中国     行业  互联网科技 +
+ +
+
+
+
+

挑战

+ +其游戏业务是世界上最大的游戏业务之一,但这不是网易为中国消费者提供的所有。公司还经营电子商务、广告、音乐流媒体、在线教育和电子邮件平台;其中最后一个服务有近10亿用户通过网站使用免费的电子邮件服务,如163.com。2015 年,为所有这些系统提供基础设施的网易云团队意识到,他们的研发流程正在减缓开发人员的速度。网易云和容器服务架构师冯长健表示:“我们的用户需要自己准备所有基础设施。”“我们希望通过无服务器容器服务自动为用户提供基础设施和工具。” +

+

解决方案

+ +在考虑构建自己的业务流程解决方案后,网易决定将其私有云平台建立在 Kubernetes 的基础上。这项技术来自 Google,这一事实让团队有信心,它能够跟上网易的规模。“经过2到3个月的评估,我们相信它能满足我们的需求,”冯长健说。该团队于 2015 年开始与 Kubernetes 合作,那会它甚至还不是1.0版本。如今,网易内部云平台还使用了 CNCF 项目 PrometheusEnvoyHarborgRPCHelm, 在生产集群中运行 10000 个节点,并可支持集群多达 30000 个节点。基于对内部平台的学习,公司向外部客户推出了基于 Kubernetes 的云和微服务型 PaaS 产品,网易轻舟微服务。 + + +

+

影响

+ +网易团队报告说,Kubernetes 已经提高了研发效率一倍多,部署效率提高了 2.8倍。“过去,如果我们想要进行升级,我们需要与其他团队合作,甚至加入其他部门,”冯长健说。“我们需要专人来准备一切,需要花费约半个小时。现在我们只需 5 分钟即可完成。”新平台还允许使用 GPU 和 CPU 资源进行混合部署。“以前,如果我们将所有资源都用于 GPU,则 CPU 的备用资源将没有。但是现在,由于混合部署,我们有了很大的改进,”他说。这些改进也提高了资源的利用率。 +
+
+ +
+
+
+ + “系统可以在单个群集中支持 30000 个节点。在生产中,我们在单个群集中获取到了 10000 个节点的数据。整个内部系统都在使用该系统进行开发、测试和生产。”

— 曾宇兴,网易架构师
+
+
+
+
+ +

其游戏业务是世界第五大游戏业务,但这不是网易为消费者提供的所有业务。

公司还在中国经营电子商务、广告、音乐流媒体、在线教育和电子邮件平台;其中最后一个服务是有近10亿用户使用的网站,如163.com126.com免费电子邮件服务。有了这样的规模,为所有这些系统提供基础设施的网易云团队在 2015 年就意识到,他们的研发流程使得开发人员难以跟上需求。网易云和容器服务架构师冯长健表示:“我们的用户需要自己准备所有基础设施。”“我们渴望通过无服务器容器服务自动为用户提供基础设施和工具。”

+ +在考虑构建自己的业务流程解决方案后,网易决定将其私有云平台建立在 Kubernetes 的基础上。这项技术来自谷歌,这一事实让团队有信心,它能够跟上网易的规模。“经过2到3个月的评估,我们相信它能满足我们的需求,”冯长健说。 +
+
+
+
+ +“我们利用 Kubernetes 的可编程性,构建一个平台,以满足内部客户对升级和部署的需求。”

- 冯长健,网易云和容器托管平台架构师
+
+
+
+
+ +该团队于 2015 年开始采用 Kubernetes,那会它甚至还不是1.0版本,因为它相对易于使用,并且使 DevOps 在公司中得以实现。“我们放弃了 Kubernetes 的一些概念;我们只想使用标准化框架,”冯长健说。“我们利用 Kubernetes 的可编程性,构建一个平台,以满足内部客户对升级和部署的需求。”

+ +团队首先专注于构建容器平台以更好地管理资源,然后通过添加内部系统(如监视)来改进对微服务的支持。这意味着整合了 CNCF 项目 PrometheusEnvoyHarborgRPCHelm。“我们正在努力提供简化和标准化的流程,以便我们的用户和客户能够利用我们的最佳实践,”冯长健说。

+ +团队正在继续改进。例如,企业的电子商务部分需要利用混合部署,过去需要使用两个单独的平台:基础架构即服务平台和 Kubernetes 平台。最近,网易创建了一个跨平台应用程序,支持将两者同时使用单命令部署。 +
+
+
+
+ +“只要公司拥有成熟的团队和足够的开发人员,我认为 Kubernetes 是一个很好的有所助力的技术。”

- 李兰青, 网易 Kubernetes 开发人员
+
+
+
+ +
+
+ +“系统可以在单个群集中支持 30000 个节点。在生产中,我们在单个群集中获取到了 10000 个节点的数据。整个内部系统都在使用该系统进行开发、测试和生产。”

+ +网易团队报告说,Kubernetes 已经提高了研发效率一倍多。部署效率提高了 2.8倍。“过去,如果我们想要进行升级,我们需要与其他团队合作,甚至加入其他部门,”冯长健说。“我们需要专人来准备一切,需要花费约半个小时。现在我们只需 5 分钟即可完成。”新平台还允许使用 GPU 和 CPU 资源进行混合部署。“以前,如果我们将所有资源都用于 GPU,则 CPU 的备用资源将没有。但是现在,由于混合部署,我们有了很大的改进,”他说。这些改进也提高了资源的利用率。 + +
+ +
+
+ +“通过与这个社区接触,我们可以从中获得一些经验,我们也可以从中获益。我们可以看到社区所关心的问题和挑战,以便我们参与其中。”

- 李兰青, 网易 Kubernetes 开发人员
+
+
+
+ +基于使用内部平台的成果和学习,公司向外部客户推出了基于 Kubernetes 的云和微服务型 PaaS 产品,网易轻舟微服务。“我们的想法是,我们可以找到我们的游戏和电子商务以及云音乐提供商遇到的问题,所以我们可以整合他们的体验,并提供一个平台,以满足所有用户的需求,”曾宇兴说。

+ +无论是否使用网易产品,该团队鼓励其他公司尝试 Kubernetes。Kubernetes 开发者李兰青表示:“只要公司拥有成熟的团队和足够的开发人员,我认为 Kubernetes 是一个很好的技术,可以帮助他们。”

+ +作为最终用户和供应商,网易已经更多地参与社区,向其他公司学习,分享他们所做的工作。该团队一直在为 Harbor 和 Envoy 项目做出贡献,在网易进行规模测试技术时提供反馈。“我们是一个团队,专注于应对微服务架构的挑战,”冯长健说。“通过与这个社区接触,我们可以从中获得一些经验,我们也可以从中获益。我们可以看到社区所关心的问题和挑战,以便我们参与其中。” +
+
diff --git a/content/zh/case-studies/netease/netease_featured_logo.png b/content/zh/case-studies/netease/netease_featured_logo.png new file mode 100644 index 0000000000000..5700b940f34af Binary files /dev/null and b/content/zh/case-studies/netease/netease_featured_logo.png differ diff --git a/content/zh/case-studies/nordstrom/index.html b/content/zh/case-studies/nordstrom/index.html new file mode 100644 index 0000000000000..40cfc7642d77f --- /dev/null +++ b/content/zh/case-studies/nordstrom/index.html @@ -0,0 +1,152 @@ +--- +title: 案例研究:Nordstrom +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +--- + + + +
+

案例研究:
在艰难的零售环境下寻找数百万的潜在成本节约 + + +

+ +
+ + + +
+ 公司  Nordstrom     地点  西雅图, 华盛顿     行业  零售 +
+ +
+
+
+
+ + +

挑战

+Nordstrom 希望提高其技术运营的效率和速度,其中包括 Nordstrom.com 电子商务网站。与此同时,Nordstrom 技术公司正在寻找压缩技术运营成本的方法。 + +
+ + +

解决方案

+在四年前采用 DevOps 转型并启动持续集成/部署 (CI/CD)项目后,该公司将部署时间从 3 个月缩短到 30 分钟。但是他们想在部署环境上走得更快,所以他们开始他们的云原生之旅,采用与 Kubernetes 协调的Docker容器。 + +
+ + +
+ +
+ + + +

影响

+为 Nordstrom 构建 Kubernetes 企业平台的团队高级工程师 Dhawal Patel 说,“使用 Kubernetes 的 Nordstrom 技术开发人员现在项目部署得更快,并且能够只专注于编写应用程序。”此外,该团队还提高了运营效率,根据工作负载将 CPU 利用率从 5 倍提高到 12 倍。Patel 说:“我们运行了数千台虚拟机 (VM),但无法有效地使用所有这些资源。借助 Kubernetes ,我们甚至不需要尝试去提高群集的效率,就能使运营效率增长 10 倍。” + +
+
+
+
+
+ +“我们一直在寻找通过技术进行优化和提供更多价值的方法。通过 Kubernetes ,我们在开发效率和运营效率这两方面取得了示范性的提升。这是一个双赢。” + +

-— Dhawal Patel, Nordstrom 高级工程师
+
+
+
+
+ +当 Dhawal Patel 五年前加入 Nordstrom ,担任该零售商网站的应用程序开发人员时,他意识到有机会帮助加快开发周期。 +

+ +在早期的 DevOps 时代,,Nordstrom 技术仍然遵循传统的孤岛团队和功能模型。Patel 说:“作为开发人员,我花在维护环境上的时间比编写代码和为业务增加价值的时间要多。我对此充满热情,因此我有机会参与帮助修复它。” +

+ +公司也渴望加快步伐,并在 2013 年启动了首个持续集成/部署 (CI/CD)项目。该项目是 Nordstrom 云原生之旅的第一步。 +

+ +开发人员和运营团队成员构建了一个 CI/CD 管道,在内部使用公司的服务器。团队选择了 Chef ,并编写了自动虚拟 IP 创建、服务器和负载均衡的指导手册。Patel 说:“项目完成后,部署时间从 3 个月减少到 30 分钟。我们仍有开发、测试、暂存、然后生产等多个环境需要重新部署。之后,每个运行 Chef 说明书的环境部署都只花 30 分钟。在那个时候,这是一个巨大的成就。” +

+ +但是,新环境仍然需要很长时间才能出现,因此下一步是在云中工作。如今,Nordstrom Technology 已经构建了一个企业平台,允许公司的1500 名开发人员在云中部署以 Docker 容器身份运行的应用程序,这些应用程序由 Kubernetes 进行编排。 +
+
+
+
+ +“了解到早期的社区支持和项目迭代指标,我们肯定 Kubernetes 一定会成功的,因此我们以 Kubernetes 为核心重建了我们的系统。” +
+
+
+
+ + +Patel 说:“云提供了对资源的更快访问,因为我们在内部需要花数周时间才能部署一个虚拟机 (VM)来提供服务。但现在我们可以做同样的事情,只需五分钟。” +

+ +Nordstrom 首次尝试在集群上调度容器,是基于 CoreOS fleet 的原生系统。他们开始使用该系统做一些概念验证项目,直到 Kubernetes 1.0发布时才将正式项目迁移到里面。Nordstrom 的 Kubernetes 团队经理 Marius Grigoriu 表示:“了解到早期的社区支持和项目迭代指标,我们肯定 Kubernetes 一定会成功的,因此我们以 Kubernetes 为核心重建了我们的系统。” + +虽然 Kubernetes 通常被视为微服务的平台,但在 Nordstrom 担任关键生产角色的 Kubernetes 上推出的第一个应用程序是 Jira。Patel 承认:“这不是我们希望作为第一个应用程序获得的理想微服务,但致力于此应用程序的团队对 Docker 和 Kubernetes 非常热情,他们希望尝试一下。他们的应用程序部署在内部运行,并希望将其移动到 Kubernetes。 +

+ +对于加入的团队来说,这些好处是立竿见影的。Grigoriu 说:“在我们的 Kubernetes 集群中运行的团队喜欢这样一个事实,即他们担心的问题更少,他们不需要管理基础设施或操作系统。早期使用者喜欢 Kubernetes 的声明特性,让他们不得不处理的面积减少。 +
+
+
+
+ +Grigoriu 说:“在我们的 Kubernetes 集群中运行的团队喜欢这样一个事实,即他们担心的问题更少,他们不需要管理基础设施或操作系统。早期使用者喜欢 Kubernetes 的声明特性,让他们不得不处理的面积减少。” +
+
+ +
+
+ +为了支持这些早期使用者,Patel 的团队开始发展集群并构建生产级服务。“我们与 Prometheus 集成了监控功能,并配有 Grafana 前端;我们使用 Fluentd 将日志推送到 Elasticsearch ,从而提供日志聚合”Patel 说。该团队还增加了数十个开源组件,包括 CNCF 项目,而且把这些成果都贡献给了 Kubernetes 、Terraform 和 kube2iam 。 +

+ +现在有60多个开发团队在 Nordstrom 上运行 Kubernetes ,随着成功案例的涌现,更多的团队加入 +进来。Patel 说:“我们最初的客户群,那些愿意尝试这些的客户群,现在已经开始向后续用户宣传。一个早期使用者拥有 Docker 容器,他不知道如何在生产中运行它。我们和他坐在一起,在15分钟内,我们将其部署到生产中。他认为这是惊人的,他所在的组织更多的人开始加入进来。” +

+ +对于 Nordstrom 而言,云原生极大地提高了开发和运营 +效率。现在,使用 Kubernetes 的开发人员部署速度更快,可以专注于在其应用程序中构建价值。一个团队从 25 分钟的合并开始,通过在云中启动虚拟机来进行部署。切换到 Kubernetes 的过程速度是原来 5 倍,将合并时间缩短为 5 分钟。 +
+ +
+
+ +“借助 Kubernetes ,我们甚至不需要尝试去提高群集的效率,目前 CPU 利用率为 40%,较之前增长了 10 倍。我们正在运行 2600 多个客户 pod ,如果它们直接进入云,这些 Pod 将是 2600 多个 VM。我们现在在 40 台 VM 上运行它们,因此这大大降低了运营开销。 +
+
+ +
+ +速度是伟大的,并且很容易证明,但也许更大的影响在于运营效率。Patel 说:“我们在 AWS 上运行了数千个 VM ,它们的总体平均 CPU 利用率约为 4%。借助 Kubernetes ,我们甚至不需要尝试去提高群集的效率,目前 CPU 利用率为 40%,较之前增长了 10 倍。我们正在运行 2600 多个客户 pod ,如果它们直接进入云,这些 Pod 将是 2600 多个 VM。我们现在在 40 台 VM 上运行它们,因此这大大降低了运营开销。 +

+ +Patel 说:“如果我们能构建一个本地 Kubernetes 集群,我们就能将云的力量带到本地快速调配资源。然后,对于开发人员,他们的接口是Kubernetes;他们甚至可能没有意识到或不关心他们的服务现在部署在内部,因为他们只与 Kubernetes 合作。 + +因此,Patel 热切关注 Kubernetes 多集群能力的发展。他说:“有了集群联合,我们可以将内部部署作为主群集,将云作为辅助可突发集群。因此,当有周年销售或黑色星期五销售,我们需要更多的容器时,我们可以去云。” +

+ +这种可能性以及 Grigoriu 和 Patel 的团队已经使用Kubernetes所提供的影响,是 Nordstrom 最初在云原生之旅中所起 +的作用。Grigoriu 说:“在当下的零售模式下,我们正在努力在力所能及的地方建立响应能力和灵活性。Kubernetes 使得为开发端和运维端同时带来效率的提升,这是一个双赢。” +
+
diff --git a/content/zh/case-studies/nordstrom/nordstrom_featured_logo.png b/content/zh/case-studies/nordstrom/nordstrom_featured_logo.png new file mode 100644 index 0000000000000..a557ffa82f12e Binary files /dev/null and b/content/zh/case-studies/nordstrom/nordstrom_featured_logo.png differ diff --git a/content/zh/case-studies/philips/index.html b/content/zh/case-studies/philips/index.html new file mode 100644 index 0000000000000..e45d41a776baa --- /dev/null +++ b/content/zh/case-studies/philips/index.html @@ -0,0 +1,4 @@ +--- +title: Philips +content_url: https://cloud.google.com/customers/philips/ +--- \ No newline at end of file diff --git a/content/zh/case-studies/philips/philips_logo.png b/content/zh/case-studies/philips/philips_logo.png new file mode 100644 index 0000000000000..9ba3421a61b81 Binary files /dev/null and b/content/zh/case-studies/philips/philips_logo.png differ diff --git a/content/zh/case-studies/pokemon-go/index.html b/content/zh/case-studies/pokemon-go/index.html new file mode 100644 index 0000000000000..ed4e168019236 --- /dev/null +++ b/content/zh/case-studies/pokemon-go/index.html @@ -0,0 +1,4 @@ +--- +title: Pokemon GO +content_url: https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html +--- \ No newline at end of file diff --git a/content/zh/case-studies/pokemon-go/pokemon_go_logo.png b/content/zh/case-studies/pokemon-go/pokemon_go_logo.png new file mode 100644 index 0000000000000..3cf2b5c7ef63d Binary files /dev/null and b/content/zh/case-studies/pokemon-go/pokemon_go_logo.png differ diff --git a/content/zh/case-studies/samsung-sds/index.html b/content/zh/case-studies/samsung-sds/index.html new file mode 100644 index 0000000000000..db4aa479abc1e --- /dev/null +++ b/content/zh/case-studies/samsung-sds/index.html @@ -0,0 +1,4 @@ +--- +title: Samsung SDS +content_url: http://www.nextplatform.com/2016/05/24/samsung-experts-put-kubernetes-paces/ +--- \ No newline at end of file diff --git a/content/zh/case-studies/samsung-sds/sds_logo.png b/content/zh/case-studies/samsung-sds/sds_logo.png new file mode 100644 index 0000000000000..0a172df65d7e1 Binary files /dev/null and b/content/zh/case-studies/samsung-sds/sds_logo.png differ diff --git a/content/zh/case-studies/soundcloud/index.html b/content/zh/case-studies/soundcloud/index.html new file mode 100644 index 0000000000000..c3c99ba715c4c --- /dev/null +++ b/content/zh/case-studies/soundcloud/index.html @@ -0,0 +1,4 @@ +--- +title: SoundCloud +content_url: https://www.youtube.com/watch?v=5378N5iLb2Q +--- diff --git a/content/zh/case-studies/soundcloud/soundcloud_logo.png b/content/zh/case-studies/soundcloud/soundcloud_logo.png new file mode 100644 index 0000000000000..f8c12f05b5edf Binary files /dev/null and b/content/zh/case-studies/soundcloud/soundcloud_logo.png differ diff --git a/content/zh/case-studies/squarespace/index.html b/content/zh/case-studies/squarespace/index.html new file mode 100644 index 0000000000000..b78180f52c295 --- /dev/null +++ b/content/zh/case-studies/squarespace/index.html @@ -0,0 +1,224 @@ +--- +title: Squarespace 案例分析 +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +--- + + + + + +
+

案例分析:
+
Squarespace: 借力 Kubernetes 提升效率和可靠性
+

+
+ + + +
+ 公司名  Squarespace     地址  纽约市,纽约州     行业  软件服务,网站构建平台 +
+ +
+
+
+
+ +

挑战

+ 自从 2014 年,我们从 monolith 架构移植到微服务架构, + “虽然解决了开发端的问题,但却带来了架构组的问题”,Squarespace 网站可靠性组的主任工程师 Kevin Lynch 说道。 + “5000 个 VM 主机上的部署过程,让每个人都举步维艰。” + +
+ +

解决方案

+ 网站可靠性组开始尝试使用不同的容器编排平台,然后发现 Kubernetes “解决了我们所有的既有问题”,Lynch 说道。于是整个公司在 2016 年开始在自己的数据中心中运行 Kubernetes 集群。 +
+ +
+ + + +

影响

+自从 Squarespace 开始全面使用 Kubernetes,伴随着网络技术栈的革新,部署时间大幅减少85%。 +以前,他们的 VM 部署需要耗费半个小时;现在,Lynch 提到,“一个人可以生成一个模板应用,在五分钟内部署,并将实例容器化,并在模拟环境下运行。”正因为如此,“开发效率节省了大量的成本。” +他又补充道,“当我们开始用 Kubernetes 时,我们可能只有十几个微服务。而现在的任务栏里面已经有两倍多的微服务正在进行中。” +Kubernetes 也同样提升了可靠性:“如果一个节点宕掉,马上会重新调度一个新的节点,没有任何性能上的影响。” + +
+ +
+
+
+
+ +

“一旦你验证了 Kubernetes 可以解决一个问题,每个人都会立即着手解决其它的问题,无需你的布道。” +

— Kevin Lynch,Squarespace 网站可靠性组的主任工程师
+
+
+
+
+ +

从 2003 年宿舍起步, Squarespace 已经为数百万人提供了网站构建服务。

+ + + + 但在幕后,公司的单体应用却让开发人员在平台创新上举步维艰。所以在 2014 年,公司决定”走微服务之路”,Kevin Lynch 提到,Squarespace 网站稳定性组的主任工程师。 + “但是我们还是一直在自己的 vCenter VMware 虚拟机[我们自己的数据中心]上部署应用。微服务解决了开发端的问题,但是让问题转变到了基础架构组这一边。我们在5000个虚拟机主机上的部署流程让每个人的开发效率都提高不起来。” + + + + 在尝试过另外一个容器编排平台,“非常痛苦地拆解它”,Lynch 说道,我们组开始在 2016 年年中尝试 Kubernetes,发现它“能解决我们所有的问题”。 + 将 Kubernetes 部署在数据中心,而非公有云上是我们最大的挑战,但在当时,并没有很多其它的公司会这么做。 + “我们必须要自己摸索出如何在自己的基础架构中部署它,我们也必须要将其和我们其它的应用做集成,”Lynch补充道。

+ + + + 与此同时,Squarespace 的网络工程组也正在革新它们的网络技术栈,从传统的 L2 网络转变为 L3 脊叶网络架构。 + “” Lynch 说道,“它给了我们服务器直接通过架顶交换机通信的能力。我们使用 Calico 作为 + Kubernetes 的 CNI 网络插件”, + 因而,我们可以为每个 Kubernetes pod 分配 IP 地址,并将它们和其它仍在虚拟机中创建的服务无缝衔接。 + +
+
+ +
+ +
+ 在尝试过另外一个容器编排平台,“非常痛苦地拆解它”,Lynch 说道,我们组开始在 2016 年年中尝试 Kubernetes,发现它“能解决我们所有的问题”。 +
+
+ +
+
+ + + 几个月的时间,它们就有了一个稳定的集群供内部使用,并开始在生产环境下使用 Kubernetes。 + 他们同时还在自己的云原生技术栈中用到了 Zipkin 和 CNCF 项目 Prometheus and fluentd 。 + “我们换到 Kubernetes,就像进入了一个新世界,我们也同时改进了其它的工具,” Lynch 说道。“它让我们简化了流程,因而,我们才能更加方便地从模板中创建整个微服务项目,生成代码和部署管道,生成 Docker 文件, + 并迅速地将可用的、可部署的项目发布到 Kubernetes 集群上。”在 Dev/QA/Stage/Prod 不同环境间的部署也变得 “异常的简单,” Lynch 补充道。 + “现在,环境间的配置差异变得很小。” + +

+ + + 而且整个部署过程只需要五分钟,和虚拟机部署相比,几乎节约了 85% 的时间。 + “从端到端可能要半个小时,这还没有考虑可能需要基础架构工程师来做这方面的工作,因而,也还有一些业务上的延时。” +

+ + + 部署变快之后,“开发效率节省了大量的成本,” Lynch 提到,“我们有个组想要实现新的文件存储服务,他们就径直和我们的存储后来做了集成,而不需要我们的参与”,这在采用 Kubernetes 之前是不可想象的。 + 他又补充道:“在我们开始 Kubernetes 项目时,我们可能只有十几个微服务。而现在的任务栏里面已经有两倍多的微服务正在进行中。” + + + +
+
+
+
+ + + “我们换到 Kubernetes,就像进入了一个新世界....它让我们简化了流程,因而,我们才能更加方便地从模板中创建整个微服务项目,” + Lynch 说道。整个部署过程只需要五分钟,和虚拟机部署相比,几乎节约了 85% 的时间。 +
+
+ +
+
+ + + 同样在应用程序的可靠性方面也有积极的影响。“当我们在部署虚拟机时,我们需要工具来保障服务散布在机架间,可以承受失败,”他说道,“Kubernetes 正好可以做到这一点。如果节点宕掉,可以马上重新调度,没有性能影响。” +

+ + + 另一个很大的好处就是扩缩容。“按照我们使用 VMware 的方式,扩缩容好像不可能实现,”Lynch 说道,“但现在,我们可以直接通过 Kubernetes 加入合适的扩缩容功能,然后,随着需求的增加而扩容。开箱即用!” +

+ + + 针对刚开始使用 Kubernetes 的人,Lynch 说他最后的建议就是“快速失败”:“一旦计划后,马上执行。Kubernetes 真的是非常适合快速实验,看看是否可行。” + +
+ +
+
+ + + “当我们在部署虚拟机时,我们需要工具来保障服务散布在机架间,可以承受失败,”他说道,“Kubernetes 正好可以做到这一点。如果节点宕掉,可以马上重新调度,没有性能影响。” + +
+
+ +
+ + + Lynch 和他的小组正准备开源一些他们的工具,这些工具用来延展 Kubernetes,将其作为 API 使用。 + 第一个工具在 pod 将依赖应用作为容器注入。 + “当你在发布应用时,常常需要一系列的依赖应用,例如,日志用的 fluentd,” 他解释道。 + 有了这个工具,开发人员就不需要担心配置了。 + +

+ + + 自此之后,Squarespace 所有新的微服务都将直接部署到 Kubernetes 上,而最终的目标是要扩大到所有的服务上。 + 现在已经有四分之一的服务已经移植完。“我的单体应用将是最后一个被移植的,仅仅是以为它太大、太复杂,”Lynch 说道。 + “但现在我已经看到其它的服务已经被移植到 Kubernetes 上,例如文件存储服务。有人解决了,而且并不复杂。 + 所以我坚信如果我们着手解决它,很可能回避我们所担心的要轻松许多。也许我应该接受自己的建议,“快速失败”!” + +
+ +
diff --git a/content/zh/case-studies/squarespace/squarespace_featured_logo.png b/content/zh/case-studies/squarespace/squarespace_featured_logo.png new file mode 100644 index 0000000000000..551b6da32119d Binary files /dev/null and b/content/zh/case-studies/squarespace/squarespace_featured_logo.png differ diff --git a/content/zh/case-studies/wepay/index.html b/content/zh/case-studies/wepay/index.html new file mode 100644 index 0000000000000..b8ce8201d5f5b --- /dev/null +++ b/content/zh/case-studies/wepay/index.html @@ -0,0 +1,4 @@ +--- +title: WePay +content_url: http://thenewstack.io/wepay-kubernetes-changed-business/ +--- \ No newline at end of file diff --git a/content/zh/case-studies/wepay/wepay_logo.png b/content/zh/case-studies/wepay/wepay_logo.png new file mode 100644 index 0000000000000..4e35dd8fd694a Binary files /dev/null and b/content/zh/case-studies/wepay/wepay_logo.png differ diff --git a/content/zh/case-studies/wikimedia/index.html b/content/zh/case-studies/wikimedia/index.html new file mode 100644 index 0000000000000..ab6452bfc3ea7 --- /dev/null +++ b/content/zh/case-studies/wikimedia/index.html @@ -0,0 +1,118 @@ +--- +title: 案例研究:Wikimedia + +class: gridPage +cid: caseStudies +--- + +
+

案例研究:Wikimedia

+
+ +
+
+
+ +

利用 Kubernetes 构建工具提升世界的维基

+

+ +非营利的 Wikimedia 基金会运营着一些世界上最大的合作编辑参考项目,包括 Wikipedia。为了帮助用户维护和使用 wiki,它运行 Wikimedia 工具实验室,这是一个托管环境,为社区开发人员工作的工具和机器人,以帮助编辑和其他志愿者做他们的工作,包括减少破坏。Wikimedia 工具实验室周围的社区在近10年前开始形成。 +

+
+ Wikimedia +

+ +“ Wikimedia 工具实验室对于确保世界各地的 wiki 尽可能工作至关重要。因为它有机地生长了近10年,它已成为一个极具挑战性的环境,难以维持。它就像一个大的泥球,你真的看不透它。借助 Kubernetes,可以简化环境,使开发人员能够更轻松地构建使 wiki 运行得更好的工具。” +

+ +

— Yuvi Panda, Wikimedia 基金会和 Wikimedia 工具实验室的运维工程师

+
+
+
+
+ +
+
+
+
+

挑战:

+
    + +
  • 简化复杂、难以管理的基础架构
  • + +
  • 允许开发人员使用现有技术继续编写工具和机器人
  • +
+
+
+ +

为什么要使用 Kubernetes

+
    + +
  • Wikimedia 工具实验室之所以选择 Kubernetes,是因为它可以模仿现有的工作流程,同时降低复杂性。
  • +
+
+
+ +

解决方案:

+
    + +
  • 将旧系统和复杂的基础设施迁移到库贝内特斯
  • +
+
+
+ +

结果:

+
    + +
  • 占 Web 流量 40% 以上的 Web 工具的 20% 现在都在 Kubernetes 上运行
  • + +
  • 一个 25 节点集群可跟上每个新 Kubernetes 版本
  • + +
  • 由于 Kubernetes 数千行旧代码被删除
  • +
+
+
+
+
+ +
+
+
+ +

使用 Kubernetes 提供维护 wiki 的工具

+

+ + Wikimedia 工具实验室由四名半付费员工和两名志愿者管理。基础架构无法使开发人员轻松或直观地构建机器人和其他工具,使 wiki 更易于工作。Yuvi说,“它非常混乱。我们有很多的 Perl 和 Bash 缠绕在上面。一切都是超级脆弱。” +

+

+ + 为了解决这个问题,Wikimedia 工具实验室将其部分基础设施迁移到了 Kubernetes,为最终迁移整个系统做准备。Yuvi 说,Kubernetes 大大简化了维护。目标是允许创建机器人和其他工具的开发人员使用他们想要的任何开发方法,但使 Wikimedia 工具实验室更容易维护托管和共享它们所需的基础结构。 +

+

+ + “借助 Kubernetes,我能够删除大量我们定制的代码,这使得所有内容更易于维护。我们的用户代码也以比以前更稳定的方式运行,” Yuvi 说。 +

+
+
+
+ +
+
+
+ +

简化基础架构让 wiki 更好地运行

+

+ + Wikimedia 工具实验室在最初的 Kubernetes 部署中取得了巨大成功。旧代码正在被简化和消除,使开发人员不必改变他们编写工具和机器人的方式,这些工具和机器人的运行方式比过去更稳定。付费员工和志愿者能够更好地解决问题。 +

+

+ + 将来,随着更完整的迁移到 Kubernetes,Wikimedia 工具实验室希望使托管和维护帮助在世界各地运行 wiki 的机器人和工具变得更加容易。该工具实验室已经托管了来自 800 名志愿者的大约 1300 个工具和机器人,每天提交更多工具和机器人。占 Web 流量 60% 以上的 20% 的工具实验室 Web 工具现在运行在 Kubernetes 上。该工具实验室有一个 25 节点群集,可跟上每个新的 Kubernetes 版本。许多现有的 Web 工具正在迁移到 Kubernetes。 +

+

+ + “我们的目标是确保世界各地的人们能够尽可能轻松地分享知识。Kubernetes 通过让世界各地的 wiki 更容易拥有蓬勃发展所需的工具,从而帮助到您,” Yuvi 说。 +

+
+
+
diff --git a/content/zh/case-studies/wikimedia/wikimedia_featured.png b/content/zh/case-studies/wikimedia/wikimedia_featured.png new file mode 100644 index 0000000000000..7b1f89ac98490 Binary files /dev/null and b/content/zh/case-studies/wikimedia/wikimedia_featured.png differ diff --git a/content/zh/case-studies/wikimedia/wikimedia_logo.png b/content/zh/case-studies/wikimedia/wikimedia_logo.png new file mode 100644 index 0000000000000..3ad5b63034204 Binary files /dev/null and b/content/zh/case-studies/wikimedia/wikimedia_logo.png differ diff --git a/content/zh/case-studies/wink/index.html b/content/zh/case-studies/wink/index.html new file mode 100644 index 0000000000000..db4fa13964aa9 --- /dev/null +++ b/content/zh/case-studies/wink/index.html @@ -0,0 +1,146 @@ +--- +title: 案例研究:Wink + +case_study_styles: true +cid: caseStudies +css: /css/style_wink.css +--- + +
+ +

案例研究:
+
云原生基础设施让你的智能家居互联
+

+ +
+ + + +
+ 公司  Wink     位置  纽约,纽约州     行业  物联网平台 +
+ +
+ +
+
+
+ +

挑战

+ +构建低延迟、高度可靠的基础设施,为数百万互联智能家居设备、公司消费者中心、移动应用之间的通信提供服务,强调水平可扩展性,能够快速加密所有内容和强健的连接。 +

+

解决方案

+ +全面使用 Kubernetes-Docker-CoreOS 容器的 Linux 系统。

+ +
+ +
+

影响

+ +“美国最大的两家零售商 [Home Depot 和 Walmart] 正在使用和推广 Wink 品牌和硬件,” Wink 工程主管 Kit Klein 自豪地说,不过他补充道,“这确实带来了很大的压力。这不是普通的零售商客户像技术狂热者一样追求前沿技术。这些人每天都在想要一些行之有效的东西,并且不会容忍技术方面的借口。”这进一步证明了 Klein 对 Wink 团队所构建的基础设施有多大的信心。由于 Wink 80% 的工作量在 Kubernetes-Docker-CoreOS 的统一堆栈上运行,公司已使自己能够不断创新和改进其产品和服务。克莱因说,致力于这项技术“使得在基础设施之上的建设相对容易。” +
+ +
+
+ + +
+
+ +“它不是专有的,它是完全开放的,它非常可移植。你可以跨不同的云提供商运行所有工作负载。你可以轻松地运行混合形式的 AWS,甚至引入你自己的数据中心。这就是在一个开源 Kubernetes-Docker-CoreOS 容器 Linux 系统上统一所有内容的好处。如果你只有一个 Linux 发行版/计算机映像进行验证,则具有巨大的安全优势。好处是巨大的,因为即省钱又省时间。

- KIT KLEIN, WINK 工程主管 + +
+
+ + +
+
+ +

打开一个灯泡需要多少人?

+ + +Kit Klein 拿出他的手机进行演示。只需轻扫几下,Wink 的工程主管打开由一家纽约公司开发的智能家居应用程序,然后轻触灯光按钮。“老实说,当你拿着手机,意味着你控制着灯光,”他说,“当你感觉到你的手指在屏幕上的压力,灯就打开了。开灯就和触觉反馈到你的大脑一样快。”

+ +当然,只需一根手指,不到 200 毫秒即可打开灯,或锁上门或更换恒温器。但是,让 Wink 能够帮助消费者以如此快速和轻松的速度管理其互联智能家居产品的是一个复杂的云原生基础架构,Klein 和他的团队使用开源的 CoreOS 统一系统构建并继续开发专为集群部署设计的操作系统和 Kubernetes,Kubernetes 是一个开源平台,用于跨主机集群自动部署、扩展和操作应用程序容器,提供以容器为中心的基础结构。Klein 说:“当你拥有一个庞大而复杂的相互依赖的微服务网络,需要能够发现彼此,并且需要水平可伸缩和对故障的容忍度时,这就是真正优化的原因。”“很多人最终依靠一些大型云提供商提供的专有服务来执行某些操作,但通过采用 CoreOS/Kubernetes 获得的是可移植性,而不是依赖于固定的某人。你真的可以决定自己的命运。“”

+ +事实上,Wink 做到了。公司的使命是使家庭互联无障碍,即对非技术业主来说,用户友好,价格合理,也许最重要的是,可靠。Klein 说:“如果你不相信,当你点击开关时就可以打开一盏灯,或者你在远处使用手机检查你的房子,但是反馈信息不准确,那么系统的便利性就会丧失。”这就是基础架构的用处。

+ +Wink 是在 Quirky 公司孵化的,该公司开发众包产品。Wink 应用程序于 2013 年首次推出,当时,它只控制了少数消费类产品,如 Quirky 与 GE 合作生产的 PivotPower Strip。随着智能家居产品的激增,Wink 于 2014 年在全国的 Home Depot 商店推出。其第一个项目:可以与 Honeywell 和 Chamberlain 等十几个品牌的智能产品集成的平台。最大的挑战是构建基础设施,为信息中心和产品之间的所有这些通信提供服务,重点是最大限度地提高可靠性和最小化延迟。

+ +Klein 说:“当我们最初推出时,我们正以非常快的速度尝试将第一个产品推向市场,即最低可行产品。”“很多时候,你走一条路,最终不得不回头尝试不同的东西。但是在这个特殊的情况下,我们预先做了许多工作,这导致我们作出了一个真正明智的决定,将其部署到使用 CoreOS 容器的 Linux 上。而且是在项目伊始时就这么做了。” + +
+
+ +
+
+ +“...通过 CoreOS/Kubernetes 带来的可移植性,你可以不依赖于任何人。你真的可以决定自己的命运。” +
+
+ +
+
+ +关注第一:Wink 的产品需要连接到人们家中在防火墙后面的消费设备。Klein 解释道:“由于没有 URL 这样的端点,你甚至不需要知道防火墙后面打开了哪些端口。”“因此,你基本上需要唤醒这些设备,然后与你的系统通信,然后在云和设备之间打开实时、双向通信。持续的连接真的非常重要,因为你希望尽可能减少发送消息的开销,你永远不知道什么时候有人会开灯。”

+ +使用 Wink Hub 的最早版本,当你决定打开或关闭灯光时,请求将发送到云,然后执行。Wink 软件的后续更新启用了本地控制,将许多设备的延迟缩短到大约 10 毫秒。但是,由于需要云支持的智能家居产品生态系统的集成,低延迟互联网连接仍然是一个关键的考虑因素。 +

+ +

“你基本上需要唤醒此设备,然后与你的系统通信,然后在云和设备之间打开实时、双向通信。持续的连接真的非常重要,你永远不知道什么时候有人会开灯。”

+ +此外,Wink 还有其他要求:水平可扩展性、快速加密所有内容的能力、在出现问题时可以轻松恢复的连接。Klein 说:“从一开始的整个结构来看,我们决定提供基于套接字的安全服务。”“我们总是使用某种集群技术来部署我们的服务,因此我们决定,这东西将被容器化,在 Docker 上运行。”

+ +当时,就在两年多前,Docker 还没有被广泛使用,但是正如 Klein 指出的,“技术前沿的人们当然理解它。我们开始研究现有的潜在技术。限制因素之一是我们需要部署多端口非 http/https 服务。它并不真正适合某些早期的集群技术。我们非常喜欢这个项目,最后在其它东西上使用了一段时间,但最初它过于针对 http 工作负载。”

+ +Wink 的后端工程团队决定使用 Docker 化的工作负载后,就不得不就操作系统和容器编排平台做出决定。Klein 笑着说:“很明显,你不能只是启动容器,希望一切顺利。”“你需要有一个有用的系统,以便管理工作负载的分发位置。当容器不可避免地死亡或类似的东西,重新启动它,你得有一个负载平衡器。要拥有强大的基础设施,需要进行各种内部事务管理工作。” + +
+
+ +
+
+ +Klein 笑着说:“很明显,你不能只是启动容器,希望一切顺利。”“你需要有一个有用的系统,以便管理工作负载的分发位置。当容器不可避免地死亡或类似的东西,重新启动它,你得有一个负载平衡器。要拥有强大的基础设施,需要进行各种内部事务管理工作。” +
+
+ +
+
+ +Wink 考虑直接在通用 Linux 发行版(需要安装工具来运行容器化工作负载)和集群管理系统如 Mesos(面向拥有较大团队的企业)的基础上构建,但最终将目光投向了使用 CoreOS 容器的 Linux。“一个容器优化的Linux分发系统正是我们需要的,”他说。“我们不必为了尝试采用 Linux 发行版之类的东西来安装所有内容而四处奔波。它有一个内置的容器编排系统,Fleet ,和一个易于使用的 API。它不像一些较重的解决方案那样具有丰富的功能,但我们意识到,在那一刻,这正是我们需要的。”

+ +Wink 的核心(以及经过改进的应用程序)于 2014 年 7 月推出,并进行了短期部署,并在第一个月内将服务转移到 Docker 化的 CoreOS 上部署。自那时以来,他们几乎将基础设施的其他所有部分(从第三方云到云的集成迁移到其客户服务和支付门户)迁移到使用 CoreOS 容器的 Linux 集群上。

+ +使用此设置确实需要一些额外的配置。Klein 说:“ Fleet 作为一个基本的容器编排系统确实很好,但它不负责服务实例之间的路由、配置共享、加密等。当然,所有这些功能层都可以实现,但如果你不想花费大量时间手动编写单元文件(当然没有人这样做),则需要创建一个工具来自动执行其中一些文件,我们做到了。”

+ +Wink 在 2015 年推出并集成了 CoreOS 核心技术时,很快接受了 Kubernetes 容器集群管理器,正如所承诺的那样,它最终提供了 Wink 想要的功能,并计划构建这些功能。“如果不是 Kubernetes,我们很可能采用我们为所创建的自动化工具实现的逻辑和库,并将它用于更高级别的抽象和工具,这些抽象和工具可供命令行中的非 DevOps 工程师使用,以创建和管理集群,” Klein 说。“但 Kubernetes 完全没有必要这样做,并且由比我们在集群管理方面有经验更丰富的人编写和维护,因此更好。现在,估计 Wink 80% 的工作负载是在使用 CoreOS 容器的 Linux 之上的 Kubernetes 上运行。” + +
+
+ +
+
+ +“同发展保持同步。了解决策原因。如果你了解项目背后的意图,从技术意图到某种哲学意图,那么它可以帮助你了解如何与这些系统和谐地构建系统,而不是试图与之对抗。” +
+
+ +
+
+ +Wink 的去向理由很明确:“它不是专有的,它是完全开放的,它真的很便携,” Klein 说,“它很可移植。你可以跨不同的云提供商运行所有工作负载。你可以轻松地运行混合 AWS,甚至引入你自己的数据中心。这就是在一个使用 Kubernetes-Docker-CoreOS 容器的 Linux 系统上统一所有内容的好处。如果你只有一个 Linux 发行版来尝试验证,则具有巨大的安全优势。好处是巨大的,因为既省钱又省时间。” + +Klein 承认,每个技术决策都有权衡。他表示:“对一些人来说,尖端技术将非常可怕。”“为了利用这一优势,你确实必须跟上技术。你不能把它当作一个黑盒子。同发展保持同步。了解决策原因。如果你了解项目背后的意图,从技术意图到某种哲学意图,那么它可以帮助你了解如何与这些系统和谐地构建系统,而不是试图与之对抗。” + +Wink 于 2015 年被 Flex 收购,目前控制着全国 230 万台联网设备。公司下一步怎么办?去年11月,一款新版的 “Wink Hub 2”上架,除 Home Depot 外,Walmart 商店还首次上市。Klein 自豪地说:“美国最大的两家零售商都正在使用和推广 Wink 品牌和硬件,”不过他补充道,“这确实带来了很大的压力。这不是普通的零售商客户像技术狂热者一样追求前沿技术。这些人每天都在想要一些行之有效的东西,并且不会容忍技术方面的借口。这进一步证明了 Klein 对 Wink 团队所构建的基础设施有多大的信心。” + +Wink 的工程团队从早期起就呈指数级增长,在幕后,Klein 对 Wink 使用的机器学习感到非常兴奋。“我们构建了一个数据管道的容器化小段系统,这些部分对整个团队都是有益的,并且可以有多个输出,”他说。“这就像数据管道作为微服务。”同样,Klein 指出,在使用 CoreOS 容器的 Linux 和 Kubernetes 上运行统一的系统是未来的创新的主要驱动力。“你不是每次都在重新发明轮子,”他说。“你可以专注于业务进行开发。” +
+
diff --git a/content/zh/case-studies/wink/wink_featured.png b/content/zh/case-studies/wink/wink_featured.png new file mode 100644 index 0000000000000..3c01133bef701 Binary files /dev/null and b/content/zh/case-studies/wink/wink_featured.png differ diff --git a/content/zh/case-studies/wink/wink_logo.png b/content/zh/case-studies/wink/wink_logo.png new file mode 100644 index 0000000000000..ef2ee30bf3a46 Binary files /dev/null and b/content/zh/case-studies/wink/wink_logo.png differ diff --git a/content/zh/case-studies/workiva/index.html b/content/zh/case-studies/workiva/index.html new file mode 100644 index 0000000000000..9b6a811c1ce57 --- /dev/null +++ b/content/zh/case-studies/workiva/index.html @@ -0,0 +1,147 @@ +--- +title: 案例研究:Workiva + +case_study_styles: true +cid: caseStudies +css: /css/style_workiva.css +--- + +
+ +

案例研究:
使用 OpenTracing 帮助查找瓶颈 + +

+ + +
+ + +
+ 公司  Workiva     Location  艾姆斯,爱荷华州     行业  企业软件 +
+ + +
+
+
+
+

挑战

+ +Workiva提供了一个基于云的平台,用于管理和报告业务数据。此 SaaS 产品 Wdesk 被 70% 以上的财富 500 强企业使用。随着公司从单体系统向更分散的基于微服务的系统转变,“我们有许多人在研究这个问题,他们都在不同的团队中,所以我们需要确定问题是什么,瓶颈在哪里,”高级软件架构师 MacLeod Broad 说。随着后端代码在 Google App Engine,Google Compute Engine,以及 Amazon Web Services 上运行,Workiva 需要一个还未被开发的跟踪系统。在准备公司首批使用 AWS 的产品时,Broad 的团队将新应用程序中构建的电子表格数据与 Workiva 现有系统上的旧应用程序中创建的文档相关联,该功能涉及“同步和链接”功能,从而发现了一个理想的跟踪用例:存在循环依赖关系,而优化通常证明是不影响整体速度的微优化。 + +
+ +
+ +
+

解决方案

+ +Broad 的团队推出了与平台无关的分布式跟踪系统 OpenTracing,帮助他们找出瓶颈。 +
+

影响

+ +现在在整个公司使用,OpenTracing 产生了立竿见影的效果。软件工程师 Michael Davis 报告说:“跟踪让我们能够立即了解如何改进我们的服务。通过查看每个调用的花费时间以及最常使用哪些调用的组合,我们能够在单个修复中将平均响应时间减少 95%(从 600ms 到 30ms)。” + +
+ +
+
+
+
+ +使用 OpenTracing,我的团队能够查看跟踪,并针对其他团队提出优化建议,而无需查看他们的代码。
— MacLeod Broad, Workiva 高级软件架构师
+ +
+
+
+
+ +

去年秋天,MacLeod Broad 在 Workiva 的平台团队在准备该公司的首批产品之一,当遇到障碍时就使用 Amazon Web Services

+ +早期,Workiva 的后端主要运行在Google App Engine上。但随着 Workiva 的 SaaS 产品,Wdesk,一种基于云的管理和报告业务数据平台,将客户群增长到财富 500 强公司的 70% 以上,情况发生了变化。“随着客户需求的增长和产品供应的扩大,我们开始利用更广泛的服务,如 Amazon Web Services 以及其他 Google Cloud Platform 服务,从而创建一个多供应商环境。” + + +有了这个新产品,具备“同步和链接”功能,通过它,数据“经历了一大堆服务,从新的电子表格系统[Amazon Aurora]到我们所谓的链接系统,然后通过 http 推送到我们现有的系统,然后进行一些计算,结果将传回新系统,”Broad 说。“我们当时进行优化是为了速度。我们认为做了这种极好的优化,然后它会变成一个微观优化,这并没有真正影响系统的整体速度。”

+ +Broad 团队面临的挑战听起来可能为其他公司所熟悉,这些公司也从单体系统转向更分散的基于微服务的系统。Broad 说:“我们有许多人从事这方面的工作,他们都在不同的团队中,因此很难了解问题是什么以及瓶颈在哪里。”

+ +“每个服务团队都经历着不同的架构迭代,很难了解每个团队系统中的实际内容,”他补充道。“我们有循环依赖关系,其中有三个或四个不同的服务团队不确定问题的真正位置,需要大量的来回沟通。因此,我们浪费了很多时间说,‘这个哪一部分比较慢?根据应用场景的不同,哪一部分有时很慢?随着时间推移,哪一部分会逐渐变慢?这个进程的哪一部分是异步的,因此,它是否长时间运行并不重要?我们在做的哪些是多余的,其中哪一部分是错误?’” + + +
+
+
+
+ + “跟踪系统可以一目了然地解释体系结构,缩小性能瓶颈并归零,通常只是帮助指导高级别的调查。一眼就能做到这一点,比在会议或三天的调试中要快得多,而且比从来不找出问题得过且过要快得多。”
— MACLEOD BROAD, WORKIVA 高级软件架构师
+ +
+
+
+
+ + +简而言之,它是跟踪的理想用例。Broad 说:“跟踪系统可以一目了然地解释体系结构,缩小性能瓶颈并归零,通常只是帮助在高级别指导调查。”“一眼就能做到这一点,比在会议或三天的调试中要快得多,而且比从不找出问题得过且过要快得多。”

+ +Workiva 的后端代码在 Google Compute Engine 、App Engine 和 AWS 上运行,Broad 知道他需要一个与平台无关的跟踪系统。“我们正在研究不同的追踪解决方案,”他说,“我们决定,由于市场似乎是一个不断发展的市场,我们不想被一个供应商卡住。因此,OpenTracing 似乎是避免供应商限制我们实际使用的后端的最简捷方法。”

+ +Broad 说,一旦他们将 OpenTrace 引入到第一个用例中,“跟踪使得瓶颈所在位置变得非常明显。”尽管每个人都认为是 Workiva 的现有代码减缓了速度,但事实并非如此。Broad 说:“看起来现有代码速度很慢,只是因为它能够达到到我们下一代服务的水平,而且它们需要很长时间才能处理所有这些请求。”“在瀑布图上,你可以看到每个请求在得到响应时所做的完全相同的工作。因此,对于被分页的每个响应,每个服务请求看起来都完全相同。然后,就不用费神去思考‘为什么它再次做所有这些工作?’”

+ +使用 OpenTrace 的跟踪功能,“我的团队能够查看跟踪,并针对另一个团队提出优化建议,而无需查看他们的代码,”Broad 说。“我们命名跟踪的方式可以说明请求是执行 SQL 调用还是创建 RPC。因此,可以非常简单地说,‘好吧,我们知道它能处理所有这些请求。处理一次缓存一次。’我们基本上完成了。所有这些调用立即变成了亚秒级的调用。”

+ +
+
+ +
+
+ +“我们正在研究不同的跟踪解决方案,我们决定使用 OpenTracing,由于市场似乎是一个不断发展的市场,我们不想被一个供应商卡住。因此,OpenTracing 似乎是避免供应商限制我们实际使用的后端的最简捷方法。”
— MACLEOD BROAD, WORKIVA 高级软件架构师
+ +
+
+ +
+
+ +在第一个用例成功后,参与尝试的每个人都回去重新编排了他们的产品。跟踪功能已添加到几个更多的用例中。Broad 说:“我们希望尽早度过最初的实施难关,而不会让整个部门一起渡过难关。”“现在,许多团队在启动新服务时添加它。我们现在确实比以前更将推动采用。”

+ +一些团队很快就赢了。软件工程师 Michael Davis 说:“跟踪让我们能够立即了解如何改进我们的(工作空间)服务。通过查看每个调用的花费时间以及最常使用哪些调用的组合,我们能够在单个修复中将平均响应时间减少 95%(从 600ms 到 30ms)”。

+ +Workiva 的大部分主要产品现在都使用 OpenTracing 进行跟踪,将数据推送到 Google StackDriver。即使未完全使用跟踪功能的产品,也具有一些组件和库。

+ +Broad 指出,由于一些工程师正在使用 App Engine,并且已经拥有平台的 Appstats 库分析性能的经验,因此他们不需要花太多时间才能习惯使用 OpenTracing。但其他人则有点不情愿。“我认为,使用 OpenTracing 的最大障碍是担心引入跟踪和 StackDriver 的成本会是多少,”他说。“人们也非常关心将中间件添加到他们正在处理的任何内容中。有关传递上下文以及如何完成这些工作的问题很常见。我们的许多 Go 开发人员对此都很好,因为他们已经以这样或那样的形式这样做了。我们的 Java 开发人员并不热衷于这样做,因为他们使用了其他不需要该功能的系统。”

+ +但好处显然超过了人们的担忧,而今天,Workiva 的官方政策是使用追踪。 + +事实上,Broad 认为跟踪天然符合 Workiva 现有的日志记录和指标系统。“这是我们在内部展示的方式,也是我们设计使用方式的方式,”他说。“我们的跟踪记录在与我们的应用指标和日志记录数据完全相同的机制中,并且它们被推送的方式完全相同。因此,在创建和记录所有数据时,我们对待这些数据完全一样。我们有一个内部库,用于日志记录、遥测、分析和跟踪。” + + +
+
+ +
+
+ +“跟踪让我们能够立即、可操作地洞察如何改进我们的(工作空间)服务。通过查看每个调用花费的时间以及最常使用哪些调用的组合,我们能够在单个修复中将平均响应时间减少 95%(从 600ms 到 30ms)。”
— Michael Davis, 软件工程师, Workiva
+ +
+
+ +
+
+ +对于 Workiva,OpenTracing 已成为一种重要工具,通过观察使用模式来聚焦最佳优化和确定什么是微观优化。Broad 说:“在某些项目中,我们经常假设客户正在做什么,我们针对这些疯狂的测试案例进行优化,这些案例的 1% 是同用户实际非常相符的。”“这样是非常有益的,‘好吧,我们在每个执行 X 的请求上添加 100 毫秒,如果最坏的情况,我们也只需要添加 100 毫秒,这仅发生在千分之一的请求或一百万个请求中的一个。’”

+ +与许多其他公司不同,Workiva 还跟踪客户端。Broad 说:“对我们来说,用户体验很重要,如果 RPC 执行后还需要 5 秒才能在浏览器中显示,则 RPC 执行需要 100 毫秒就不重要了。”“因此,对于我们而言,这些客户端响应时间非常重要。我们跟踪它,看看加载的哪些部分需要很长时间。我们正在研究什么是“加载”的定义。是当你访问到它,还是当它被渲染时,或者当你可以与它交互时?我们计划使用跟踪来关注和更好地了解这些内容。”

+ +这还需要根据外部和内部时钟的差异进行调整。“在时间纠正之前,这是非常恐怖的;我们的跟踪比什么都更具有误导性,” Broad 说。“因此,我们决定在响应标头上返回一个时间戳,然后让客户端根据该时间调整其时间,而不是更改其内部时钟,而只需计算客户端收到时响应时间的偏移量。如果最终出现一种不可能的情况,客户端的 RPC 调用持续了 210 毫秒但响应返回时间并不在这个范围内,那就必须得重新调用请求。”

+ +Broad 对 OpenTracing 对公司产生的影响感到兴奋,并且也在展望该技术还能实现什么。一种可能性是使用跟踪实时更新文档。他表示:“使文档与现实保持同步是一项重大挑战。”“例如,我们刚刚运行了跟踪模拟,或者我们刚刚在此新部署上运行了烟雾测试,但是结果显示架构与文档不匹配。我们可以找到是谁的责任,并通知他们进行更新。这是我希望在未来通过追踪获得的功能之一。” + +
+ +
diff --git a/content/zh/case-studies/workiva/workiva_featured_logo.png b/content/zh/case-studies/workiva/workiva_featured_logo.png new file mode 100644 index 0000000000000..9998b471049e5 Binary files /dev/null and b/content/zh/case-studies/workiva/workiva_featured_logo.png differ diff --git a/content/zh/case-studies/yahoo-japan/index.html b/content/zh/case-studies/yahoo-japan/index.html new file mode 100644 index 0000000000000..724a41ae01558 --- /dev/null +++ b/content/zh/case-studies/yahoo-japan/index.html @@ -0,0 +1,4 @@ +--- +title: Yahoo! Japan +content_url: https://kubernetes.io/blog/2016/10/kubernetes-and-openstack-at-yahoo-japan +--- \ No newline at end of file diff --git a/content/zh/case-studies/yahoo-japan/yahooJapan_logo.png b/content/zh/case-studies/yahoo-japan/yahooJapan_logo.png new file mode 100644 index 0000000000000..3cbea39598954 Binary files /dev/null and b/content/zh/case-studies/yahoo-japan/yahooJapan_logo.png differ diff --git a/content/zh/case-studies/ygrene/index.html b/content/zh/case-studies/ygrene/index.html new file mode 100644 index 0000000000000..969483ba073aa --- /dev/null +++ b/content/zh/case-studies/ygrene/index.html @@ -0,0 +1,130 @@ +--- +title: 案例研究:Ygrene + +case_study_styles: true +cid: caseStudies +css: /css/style_ygrene.css +--- + + +
+

案例研究:
Ygrene: 使用原生云为金融行业带来安全性和可扩展性 + +

+ + +
+ + +
+ 公司  Ygrene     位置  佩塔卢马,加利福尼亚州     行业  清洁能源融资 +
+ +
+
+
+
+

挑战

+ +作为一家 PACE(清洁能源资产评估)融资公司,Ygrene 自2010年以来已经为超过10亿的贷款提供资金。为了批准和处理这些贷款,“我们有很多正在聚合的数据源,而且我们也有许多系统需要对这些数据进行改动,”Ygrene 开发经理 Austin Adams 说。该公司正在使用大量服务器,“我们刚刚达到能够垂直扩展它们的极限。我们有一个非常不稳定的系统,它变得不知所措,要求只是做后台数据处理的实时。用户看到的性能很差。我们需要一个解决方案,不需要我们对代码库进行大量重构。作为一家金融公司,Ygrene 还需要确保他们安全地传输应用程序。” + +
+ +

解决方案

+ +从 Engine Yard 和 Amazon Elastic Beanstalk 上迁移了应用后,Ygrene 团队采用云原生技术和实践:使用Kubernetes来帮助垂直扩展和分配工作负载,使用 Notary 加入构建时间控制和获取使用第三方依赖的可信赖 Docker 镜像,使用Fluentd“掌握堆栈中的所有情况”,这些都运行在Amazon EC2 Spot上。 +
+ +
+ +

影响

+ +以前,部署通常需要三到四个小时,而且每周或每两周要把一些两三个月工作量的任务在系统占用低的时候进行部署。现在,他们用5分钟来配置 Kubernetes,然后用一个小时进行整体部署与烟雾测试。Adams 说:“我们每周可以部署三到四次,只需一周或两天的工作量。”“我们在工作周、白天的任意时间进行部署,甚至不需要停机。以前我们不得不请求企业批准,以关闭系统,因为即使在半夜,人们也可能正在访问服务。现在,我们可以部署、上传代码和迁移数据库,而无需关闭系统。公司获得新功能,而不必担心某些业务会丢失或延迟。”此外,通过使用 kops 项目,Ygrene 现在可以用以前成本的十分之一使用 AWS EC2 Spot 运行其 Kubernetes 集群。Adams 说,这些云原生技术“改变了可扩展性、可观察性和安全性(我们正在添加新的非常安全的数据源)的游戏。”“没有 Kubernetes、Notary 和 Fluent,我们就无法告诉投资者和团队成员,我们知道刚刚发生了什么事情。” + +
+ +
+
+
+
+ +“CNCF 项目正在帮助 Ygrene 确定整个 PACE 行业的安全性和可观察性标准。我们是一个新兴的金融企业,没有这些项目,尤其是 Kubernetes,我们不可能成为今天的行业领导者。”

— Austin Adams, Ygrene 能源基金会开发经理
+ +
+
+ +
+
+ +

在不到十年的时间里, Ygrene 就为可再生能源项目提供了超过10亿美元的贷款。

PACE (清洁能源物业评估)融资公司开发经理 Austin Adams 表示:“我们抵押房屋或商业建筑,用贷款来为任何可以节约电力、生产电力、节约用水或减少碳排放的项目提供资金支持。”

+ + +为了批准这些贷款,公司需要处理大量的承销数据。Adams 说:“我们必须要验证有关财产、公司或人员的问题,像这样的工作数以千计。因此,我们有很多正在聚合的数据源,并且我们也有大量系统需要实时对这些数据进行改动。”

+ +到 2017 年,部署和可扩展性已成为痛点。该公司已经使用了大量服务器,“我们刚刚达到能够垂直扩展的极限,”他说。迁移到 AWS Elastic Beanstalk 并不能解决问题:“Scala 服务需要来自主 Ruby on Rails 服务和不同供应商提供的大量数据,因此他们要求从我们的 Ruby 服务以一种服务器无法承受的速率获取信息。在 Elastic Beanstalk 上我们也有许多配置与应用不匹配。这仅仅是一个开始,我们也意识到我们这个系统非常不稳定。” +
+
+
+
+ +“CNCF 是众多项目惊人的孵化器。现在,我们定期查看其网页,了解是否有任何新的、可敬的高质量项目可以应用到我们的系统中。它实际上已成为我们了解自身需要什么样的软件以使我们的系统更加安全和具有可伸缩性的信息中心。”

— Austin Adams, Ygrene 能源基金会开发经理
+
+
+
+
+ + +Adams 和其他团队一起着手寻找一种具有变革性的解决方案,但“不需要我们对代码库进行巨大的重构,”他说。作为一家金融公司,和可伸缩性一样,Ygrene 需要更好的安全性。他们通过采用云原生技术找到了答案:Kubernetes 帮助纵向扩展和分配工作负载,Notary 在各个级别实现可靠的安全性,Fluentd 来提供可观察性。Adams 说:“ Kubernetes 是社区前进的方向,也是我们展望未来的证明。”

+ +有了 Kubernetes,该团队能够快速将 Ygrene 应用程序用 Docker 容器化。“我们必须改变一些实现和代码,以及系统的构建方式,” Adams 说,“但我们已经能够在一个月左右的时间内将主要系统引入 Kubernetes,然后在两个月内投入生产。对于一家金融公司来说,这已经非常快了。”

+ +怎么样?Adams 说,这些云原生技术“改变了可扩展性、可观察性和安全性(我们正在添加新的非常安全的数据源)的游戏。”“没有 Kubernetes、Notary 和 Fluent,我们就无法告诉投资者和团队成员,我们知道刚刚发生了什么事情。”

+ +Adams 说,尤其 Notary 简直就是“天赐之物”。“我们要清楚,我们针对第三方依赖项的攻击面较低,或者至少是托管的。因为我们使用 Notary 作为一个信任系统,我们也使用它作为区分,所以生产镜像由 Notary 签名,但一些开发镜像就不签署。这是为了确保未签名镜像无法进入生产集群。我们已经在测试集群中使用它,以使构建的应用更安全。” + + +
+
+
+
+ +“我们必须改变一些实现和代码,以及系统的构建方式,” Adams 说,“但我们已经能够在一个月左右的时间内将主要系统引入 Kubernetes,然后在两个月内投入生产。对于一家金融公司来说,这已经非常快了。” +
+
+ +
+
+ +通过使用 kops 项目,Ygrene 能够用以前成本的十分之一从 Elastic Beanstalk 迁移到 AWS EC2 Spot 上运行其 Kubernetes 群集。Adams 说:“以前为了扩展,我们需要增加实例大小,导致高成本产出低价值。现在,借助 Kubernetes 和 kops,我们能够在具有多个实例组的 Spot 上水平缩放。”

+ +这也帮助他们降低了在公共云中运行所带来的风险。“我们发现,基本上,如果我们能够使用中断可能性极低、无中断历史的 EC2 Spot 选择实例类,并且我们愿意付出足够高的价格,我们几乎可以得到和使用 Kubernetes 相同的保证,因为我们有足够的节点,”软件工程师 Zach Arnold 说,他领导了向 Kubernetes 的迁移。“现在,我们已经重新架构了应用程序的这些部分,使之不再位于同一台服务器上,我们可以推送到许多不同的服务器,并实现更稳定的部署。”

+ +因此,团队现在可以在一天中的任何时间传输代码。阿诺德说:“以前这样做是很危险的,因为它会拖慢整个贷款管理软件。”“但现在,我们可以在白天安全部署。” + +
+
+
+
+ +Adams 说:“以前为了扩展,我们需要增加实例大小,导致高成本产出低价值。现在,借助 Kubernetes 和 kops,我们能够在具有多个实例组的 Spot 上水平缩放。” +
+
+ +
+
+ +以前,部署通常需要三到四个小时,而且每周或每两周要把一些两三个月工作量的任务在系统占用低的时候进行部署。现在,他们用5分钟来配置 Kubernetes,然后用一个小时进行整体部署与烟雾测试。Adams 说:“我们每周可以部署三到四次,只需一周或两天的工作量。”“我们在工作周、白天的任意时间进行部署,甚至不需要停机。以前我们不得不请求企业批准,以关闭系统,因为即使在半夜,人们也可能正在访问服务。现在,我们可以部署、上传代码和迁移数据库,而无需关闭系统。公司增加新项目,而不必担心某些业务会丢失或延迟。”

+ +云原生也影响了 Ygrene 的 50 多名开发人员和承包商的工作方式。Adams 和 Arnold 花了相当长的时间“教人们思考开箱即用的”,Arnold 说。“我们最终选择了称之为“航运四S”:安全、可靠、稳妥、快速。”(有关其安全部分的更多内容,请参阅他们关于"持续黑客攻击"策略的文章。至于工程师,Adams 说,“他们已经能够跟上软件进步的步伐。我想一天结束时,开发人员会感觉更好,他们也会感觉与现代软件开发社区的联系更加紧密。”

+ +展望未来,Adams 很高兴能探索更多的 CNCF 项目,包括 SPIFFE 和 SPIRE。“ CNCF 是众多项目惊人的孵化器。现在,我们定期查看其网页,了解是否有任何新的、可敬的高质量项目可以应用到我们的系统中。它实际上已成为我们了解自身需要什么样的软件以使我们的系统更加安全和具有可伸缩性的信息中心。” + + +
+ +
diff --git a/content/zh/case-studies/ygrene/ygrene_featured_logo.png b/content/zh/case-studies/ygrene/ygrene_featured_logo.png new file mode 100644 index 0000000000000..d0d69114784c8 Binary files /dev/null and b/content/zh/case-studies/ygrene/ygrene_featured_logo.png differ diff --git a/content/zh/case-studies/zalando/index.html b/content/zh/case-studies/zalando/index.html new file mode 100644 index 0000000000000..39fc63ab1d98a --- /dev/null +++ b/content/zh/case-studies/zalando/index.html @@ -0,0 +1,132 @@ +--- +title: 案例研究:Zalando +case_study_styles: true +cid: caseStudies +css: /css/style_zalando.css +--- + +
+ +

案例研究:
欧洲领先的在线时尚平台通过云原生获得突破性进展 +

+ +
+ + +
+ 公司  Zalando     位置  柏林, 德国     行业  在线时尚平台 +
+ +
+
+
+
+

挑战

+ +Zalando 是欧洲领先的在线时尚平台,自 2008 年成立以来,经历了指数级增长。2015 年,Zalando 计划进一步扩展其原有的电子商务站点,以扩展新的服务和产品,从而开始了彻底的变革,因此形成了自主的自组织团队。这次扩展需要可以随工程组织的增长而扩展的基础架构。Zalando 的技术部门开始重写其应用程序,使其能够在云端运行,并开始将其基础架构从内部数据中心迁移到云。虽然编排没有立即被考虑,因为团队迁移到亚马逊网络服务(AWS):“我们体验过团队在 AWS 上进行基础设施架构和使用云资源时遇到的痛苦,”开发人员生产力主管 Henning Jacobs 说,“我们遇到了一些难题。对于团队和合规性来说,运营开销仍然过多。为了提供更好的支持,项目引入了集群管理。” + +
+ +
+

解决方案

+ +该公司现在使用 Kubernetes 编排在 AWS 上运行的 Docker 容器。 +
+

影响

+ +Jacobs 说,由于旧基础设施“很难正确采用新技术,而 DevOps 团队被视为瓶颈。”“现在,有了这个云基础架构,它们有了这种打包格式,可以包含任何在Linux内核上运行的东西。这使得很多人相当高兴。工程师喜欢自主。” +
+
+
+
+
+ +“我们设想所有 Zalando 交付团队在 Kubernetes 提供的最先进的、可靠且可扩展的群集基础架构上运行其容器化应用程序。”

- Henning Jacobs, Zalando 开发人员生产力主管 +
+
+
+
+
+ +

当 Henning Jacobs 于2010年来到 Zalando 时,该公司刚成立两年,有180名员工经营一家网上商店,供欧洲消费者购买时尚商品。

+ +Zalando 的开发人员生产力主管 Jacobs 说:“它最初是一个 PHP 电子商务网站,很容易上手,但无法随业务需求扩展。”

+ +当时,公司开始从德国以外扩展到其他欧洲市场。快进到今天,Zalando 现在拥有超过 14000 名员工,2016 年收入为 36 亿欧元,业务遍及 15 个国家/地区。他表示:“这种全面快速的增长和不断扩展,一生只能有一次。”

+ +能拥有像 Jacobs 这样的基础设施专家的机会是非常独特的。就在他加入公司后,公司开始在内部重写他们的所有应用。“这通常是我们的策略,”他表示。“例如,我们从我们自己的物流仓库开始,但起初不知道如何做物流软件,所以得用一些供应商软件。然后我们用自己的软件替换了它,因为使用现成的软件是没有竞争力的。需要根据特定业务需求优化这些流程。”

+ +在重写其应用程序的同时,Zalando 设定了一个目标,即从基本电子商务扩展到提供多租户的平台、大量增加的分类和样式、当天送达,甚至您自己的平台个人在线造型师

+ +扩展的需求最终引领了公司踏上云原生之旅。它采用基于微服务的软件架构,使工程团队拥有更多的项目自主权和所有权。“迁移到云是必要的,因为在数据中心中,团队不可能随心所欲。使用相同的基础架构,因此只能运行 Java 或 Python 应用,”Jacobs 说。 + +
+
+
+
+ +“迁移到云是必要的,因为在数据中心中,团队不可能随心所欲。使用相同的基础架构,因此只能运行 Java 或 Python 应用。” + +
+
+
+
+ +Zalando 开始将其基础架构从两个内部数据中心迁移到云,这需要迁移较旧的应用程序使其在云中准备就绪。“我们决定果断一些,” Jacobs 说。“我们的亚马逊网络服务基础设施是这样的:每个团队都有自己的 AWS 账户,该账户是完全隔离的,这意味着没有'提升和转移'。基本上必须重写应用程序,使其在云中准备就绪,甚至到持久层也是如此。我们勇敢地回到绘图板,重做一切,首先选择 Docker 作为通用容器化,然后从那里构建基础结构。”

+ +公司最初决定推迟编排,但随着团队迁移到 AWS,“我们看到团队在 AWS 上的基础设施和使用云资源方面遇到了难题,” Jacobs 说。

+ +Zalando 200多人的自主工程团队研究使用哪些技术,并可以使用自己的 AWS 账户操作自己的应用程序。事实证明,此设置是一项合规性挑战。即使制定了严格的游戏规则和自动化的合规性检查,工程团队和 IT 合规性在解决合规性问题方面也负担过重。Jacobs 说:"违规行为会出现,我们在扫描云基础架构时会检测到这些行为。“一切皆有可能,没有强制实施,因此您必须忍受违规行为(并解决它们),而不是一开始就防止错误。这些都会增加团队的开销,以及合规性和操作的开销。在 AWS 上启动新的 EC2 实例也需要时间,这会影响我们的部署速度。”

+ +Jacobs 说,团队意识到他们需要“利用从集群管理中获得的价值”。当他们在2015年首次将平台视为服务(PaaS)选项时,市场是支离破碎的;但“现在似乎有一个明确的赢家。使用 Kubernetes 似乎是一个很好的尝试。”

+ +Kubernetes 的过渡始于 2016 年 Zalando 的极客周期间,参与者将他们的项目部署到 Kubernetes 集群。60名技术基础设施部门的成员开始使用这项技术,之后每次会加入一支工程团队。Jacobs 说:“我们总是从与他们交谈开始,确保每个人的期望都清晰。然后,我们进行一些 Kubernetes 培训,这主要是针对我们的 CI/CD 设置的培训,因为我们的用户界面主要通过 CI/CD 系统。但是他们必须知道Kubernetes的基本概念和API。之后每周与每个团队同步,以检查其进度。一旦出现什么状况,就可以确定我们所做的改进是否正常。” + +
+
+
+
+ +一旦Zalando开始将应用迁移到Kubernetes,效果立竿见影。“Kubernetes 是我们无缝端到端开发人员体验的基石。我们能够使用单一一致且声明性的 API 将创意运送到生产中,” Jacobs 说。 +
+
+ +
+
+ +目前,Zalando正在运行最初的40个Kubernetes集群,并计划在可预见的将来进行扩展。一旦Zalando开始将申请迁移到Kubernetes,效果立竿见影。“ Kubernetes 是我们无缝端到端开发人员体验的基石。我们能够使用单一一致且声明性的 API 将创意运送到生产中,” Jacobs 说。“自愈基础架构提供了无摩擦体验,基于低级最佳实践构建了更高级别的抽象。我们设想所有 Zalando 交付团队都将在 Kubernetes 提供的最先进的可靠和可扩展群集基础架构上运行其容器化应用程序。” + +Jacobs 说,使用旧的内部基础设施,“很难正确采用新技术,而 DevOps 团队被视为瓶颈。”“现在,有了这个云基础架构,它们有了这种打包格式,可以包含运行在 Linux 内核中的任何内容。这使得很多人相当高兴。工程师喜欢自主性。”在Zalando的Kubernetes实施中出现了一些挑战。Jacobs 说:“我们是一支由七人组成的团队,为不同的工程团队提供集群,我们的目标是为所有团队提供坚如磐石的体验。”“我们不想要宠物集群。我们不想了解他们的工作量;它应该只是开箱即用。考虑到这一点,集群自动缩放非常重要。执行集群管理的方法有很多种,这不是核心的一部分。因此,我们创建了两个组件来预配群集,具有集群的注册表,并管理整个集群生命周期。”

+ +Jacobs 的团队还致力于改进Kubernetes-AWS 集成。“由于许多限制条件,需要通过基础设施来扩展每个自主团队的想法。” + +此外,“仍然缺少很多最佳实践,”Jacobs说。例如,该团队最近解决了 pod 安全策略问题。“在Kubernetes已经有一个概念,但没有记录,所以有点棘手,”他说。大型的Kubernetes社区是解决这个问题的一大帮助。为了帮助其他公司走上同样的道路,Jacobs在一份名为“在生产中运行 Kubernetes ”的文件中汇编了他的团队的经验教训。 + +
+
+ +
+
+ +“ Kubernetes API 允许我们以与云提供商无关的方式运行应用程序,这使我们能够在未来几年中自由访问 IaaS 提供商...我们期望 Kubernetes API 成为 PaaS 基础设施的全球标准,并对未来的继续旅程感到兴奋。” +
+
+
+
+ +最后,Kubernetes 使 Zalando 能够引进和维护公司为发展其平台而设想的新产品。Jacobs 说:“时尚咨询产品使用 Scala,而我们以前的基础设施也难以实现这一点。”这是一个解决方法,该团队需要平台团队提供越来越多的支持,只是因为他们使用了不同的技术。现在有了Kubernetes,它就自主了。无论工作负载是什么,该团队都可以走自己的路,而 Kubernetes 可以防止其他瓶颈。

+ +展望未来,Jacobs 将 Zalando 的新基础设施视为公司在进行的其他工程中的巨大推动因素,从新的物流软件到连接品牌的平台功能,以及数据科学家梦寐以求的产品。Jacobs说:“一个愿景是,如果你看下一部 James Bond 的电影,看看他穿的西装,你就应该能够自动订购,并在一小时内把它送到你身边。”“这是关于连接整个时尚领域。如果您遇到瓶颈,因为每个人都在同一个数据中心运行,因此限制很大,则这绝对是不可能的。需要基础设施来扩展每个自主团队的想法。”

+ +对于考虑这项技术的其他公司,Jacobs 说,他不一定建议像 Zalando 那样做。他表示:“如果你准备尝试失败,那么这样做是可以的。”“设定正确的期望是必须的。并不是一切都会起作用。重写应用和这种类型的组织更改可能会造成中断。我们移动的第一个产品至关重要。存在大量依赖关系,而且时间比预期长。也许我们应该从不那么复杂、不是业务关键的东西开始,只是为了开个好头。”

+ +但是,一旦他们到了另一边,“每个人都很清楚,没有大的选择,” Jacobs 补充说。“ Kubernetes API 允许我们以与云提供商无关的方式运行应用程序,这使我们能够在未来几年中自由访问 IaaS 提供商。Zalando 受益于迁移到 Kubernetes,因为我们能够利用现有知识创建工程平台,为我们的工程师提供灵活性和速度,同时显著降低运营开销。我们期望 Kubernetes API 成为 PaaS 基础设施的全球标准,并对未来的旅程感到兴奋。” + +
+ +
diff --git a/content/zh/case-studies/zalando/zalando_feature_logo.png b/content/zh/case-studies/zalando/zalando_feature_logo.png new file mode 100644 index 0000000000000..ba6251050d15a Binary files /dev/null and b/content/zh/case-studies/zalando/zalando_feature_logo.png differ diff --git a/content/zh/case-studies/zulily/index.html b/content/zh/case-studies/zulily/index.html index d41671470f71f..d5caf422aacd7 100644 --- a/content/zh/case-studies/zulily/index.html +++ b/content/zh/case-studies/zulily/index.html @@ -1,4 +1,4 @@ ---- -title: Zulily -content_url: https://www.youtube.com/embed/of45hYbkIZs ---- +--- +title: Zulily +content_url: https://www.youtube.com/embed/of45hYbkIZs +--- diff --git a/content/zh/community/_index.html b/content/zh/community/_index.html new file mode 100644 index 0000000000000..53cbbd068279f --- /dev/null +++ b/content/zh/community/_index.html @@ -0,0 +1,133 @@ +--- +title: 社区 +layout: basic +cid: community +--- + + + +
+
+ + +
+

保证 Kubernetes 到处都适用,每个人都喜欢。

+

在我们的Slack channel, + 讨论版, 或者 + Kubernetes-dev Google 群主上和 Kubernetes 互动。 + 同时,每周我们也有社区视频会议,讨论最新进展。参见 + 这些指导了解如何参与其中。

+

你也可以在世界各地通过我们的 + Kubernetes Meetup 社区 以及 + Kubernetes Cloud Native Meetup 社区来参与。

+
+ + + +
+

特殊兴趣小组 (Special Interest Groups,SIGs)

+

对于 Kubernetes 是如何和另外的技术协作感兴趣?了解下我们不停发展的 + SIGs 群组, + 从 AWS 和 Openstack 到 大数据和可扩展性,总会有一个适合你,如果你所关注的不在其列,也有指导帮助你成立新的 SIG。

+ +

作为 Kubernetes 社区的一员,你可以随意加入任何你感兴趣的 SIG 会议。不需要额外注册。

+
+ + + +
+

行为规范

+

Kubernetes 社区重视尊重和包容,并要求在所有场合都遵循 + 行为规范。 + 如果你在活动、会议、Slack 或是其它场合发现有任何违反行为规范的行为,请联系 + Kubernetes 行为规范委员会 + conduct@kubernetes.io. + 我们会确保您的匿名性。

+
+
+
+ + + +
+
+

与我们联系!

+

我们很希望听到你的声音,你是如何使用 Kubernetes 的,
以及我们可以将 Kubernetes 变得更美好。

+
+
+ @kubernetesio +

获取更多的资讯和更新。

+
+
+ Github 项目 +

了解项目,作出贡献。

+
+
+ #kubernetes-users +

Slack channel 是联系工程师,分享想法的最佳方法。

+
+
+ Stack Overflow +

我们的论坛是获得社区支持的最佳地点。

+
+
+
+
diff --git a/content/zh/community/code-of-conduct.md b/content/zh/community/code-of-conduct.md new file mode 100644 index 0000000000000..848c58832ed5b --- /dev/null +++ b/content/zh/community/code-of-conduct.md @@ -0,0 +1,44 @@ +--- +title: 社区 +layout: basic +cid: community +css: /css/community.css +--- + + + +
+ +

Kubernetes 社区行为规范

+ + + +Kubernetes 遵循 +CNCF 行为规范。 +CNCF 社区规范文本如下链接 +commit 0ce4694。 +如果您发现这个 CNCF 社区规范文本已经过时,请 +提交 issue。 + + + +如果你在活动、会议、Slack 或是其它场合发现有任何违反行为规范的行为,请联系[Kubernetes 行为规范委员会](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct)。 +我们会确保您的匿名性。 + +
+{{< include "/static/cncf-code-of-conduct.md" >}} +
+
diff --git a/content/zh/community/static/README.md b/content/zh/community/static/README.md new file mode 100644 index 0000000000000..6d65182dcc2cb --- /dev/null +++ b/content/zh/community/static/README.md @@ -0,0 +1,5 @@ + + +本路径下的文件从其它地方导入。 +除了版本更新,不要直接修改。 diff --git a/content/zh/community/static/cncf-code-of-conduct.md b/content/zh/community/static/cncf-code-of-conduct.md new file mode 100644 index 0000000000000..3ee025ba344fa --- /dev/null +++ b/content/zh/community/static/cncf-code-of-conduct.md @@ -0,0 +1,46 @@ + +## CNCF Community Code of Conduct v1.0 + +### Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering +an open and welcoming community, we pledge to respect all people who contribute +through reporting issues, posting feature requests, updating documentation, +submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for +everyone, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, age, +religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, + without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are not +aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers +commit themselves to fairly and consistently applying these principles to every aspect +of managing this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting +the [Kubernetes Code of Conduct Committee](https://github.com/kubernetes/community/tree/master/committee-code-of-conduct) . + +This Code of Conduct is adapted from the Contributor Covenant +(http://contributor-covenant.org), version 1.2.0, available at +http://contributor-covenant.org/version/1/2/0/ + +### CNCF Events Code of Conduct + +CNCF events are governed by the Linux Foundation [Code of Conduct](http://events.linuxfoundation.org/events/cloudnativecon/attend/code-of-conduct) available on the event page. This is designed to be compatible with the above policy and also includes more details on responding to incidents. diff --git a/content/zh/docs/_index.md b/content/zh/docs/_index.md index e31ea1aea7473..0b9545eaa6524 100644 --- a/content/zh/docs/_index.md +++ b/content/zh/docs/_index.md @@ -1,3 +1,9 @@ --- title: 文档 +weight: 5 --- + + diff --git a/content/zh/docs/admin/authorization/_index.md b/content/zh/docs/admin/authorization/_index.md new file mode 100644 index 0000000000000..7941c2705f393 --- /dev/null +++ b/content/zh/docs/admin/authorization/_index.md @@ -0,0 +1,155 @@ +--- +approvers: +- erictune +- lavalamp +- deads2k +- liggitt +title: 概述 +content_template: templates/concept +--- + +{{% capture overview %}} + +学习有关 Kubernetes 授权的更多信息,包括有关使用支持的授权模块创建策略的详细信息。 + +{{% /capture %}} + +{{% capture body %}} + +在 Kubernetes 里,您必须经过身份验证 ( 登录 ),才能授权您的请求 ( 授予访问权限 ).。有关认证的信息,请参阅[访问控制概述](/docs/admin/access-the-api/)。 + +Kubernetes 提供通用的 REST API 请求。这意味着 Kubernetes 授权可以与现有的组织或云提供商的访问控制系统一起使用,该系统可以处理除 Kubernetes API 之外的其他 API。 + +## 确定请求是允许还是被拒绝 +Kubernetes 使用 API ​​ 服务器授权 API 请求。它根据所有策略评估所有请求属性,并允许或拒绝请求。某些策略必须允许 API 请求的所有部分继续进行,这意味着默认情况下是拒绝权限。 + +( 虽然 Kubernetes 使用 API ​​服务器,访问控制和依赖特定类型对象的特定领域策略由 Admission 控制器处理。) + +当配置多个授权模块时,按顺序检查每个模块,如果有任何模块授权请求,则可以继续执行该请求。如果所有模块拒绝请求,则拒绝该请求 (HTTP 状态代码 403)。 + +## 查看您的请求属性 + +Kubernetes 仅查看以下 API 请求属性 : + +* **user** - 验证期间提供的 `user` 字符串 +* **group** - 认证用户所属的组名列表 +* **extra** - 由认证层提供的任意字符串键到字符串值的映射 +* **API** - 指示请求是否用于 API 资源 +* **Request path** - 诸如 `/api` 或 `/healthz` 的其他非资源端点的路径 ( 请参阅[kubectl](#kubectl)). +* **API request verb** - API 动词 `get`,`list`,`create`,`update`,`patch`,`watch`,`proxy`,`redirect`,`delete` 和 `deletecollection` 用于资源请求。要确定资源 API 端点的请求动词,请参阅**确定下面的请求动词**. +* **HTTP request verb** - HTTP 动词 `get`,`post`,`put` 和 `delete` 用于非资源请求 +* **Resource** - 正在访问的资源的 ID 或名称 ( 仅适用于资源请求 ),对于使用 `get`, `update`, `patch`, 和 `delete` 动词的资源请求,您必须提供资源名称。 +* **Subresource** - 正在访问的子资源 ( 仅用于资源请求 ) +* **Namespace** - 正在被访问的对象的命名空间 ( 仅针对命名空间的资源请求 ) +* **API group** - 正在访问的 API 组 ( 仅用于资源请求 ). 一个空字符串指定[核心 API 组](/docs/api/). + +## 确定请求动词 + +要确定资源 API 端点的请求动词,请查看所使用的 HTTP 动词以及请求是否对单个资源或资源集合进行操作 : + +HTTP 动词 | 请求动词 +---------- | --------------- +POST | 创建 +GET,HEAD | 获取 ( 个人资源 ),列表 ( 集合 ) +PUT | 更新 +PATCH | 补丁 +DELETE| 删除 ( 个人资源 ),删除 ( 收藏 ) + +Kubernetes 有时会使用专门的动词检查授权以获得额外的权限。例如 : + +* [PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/) 在 `extensions` API 组中的 `podsecuritypolicies` 资源上检查 `use` 动词的授权。 +* [RBAC](/docs/admin/authorization/rbac/#privilege-escalation-prevention-and-bootstrapping) 在 `rbac.authorization.k8s.io` API 组中的 `roles` 和 `clusterroles` 资源上检查 `bind` 动词的授权。 +* [认证](/docs/admin/authentication/) 在核心 API 组中的 `users`,`groups` 和 `serviceaccounts` 上的 `impersonate` 动词的授权以及 `authentication.k8s.io` API 组中的 `userextras` 进行层次检查。 + +## 授权模块 +* **ABAC 模式** - 基于属性的访问控制 (ABAC) 定义了访问控制范例,通过使用将属性组合在一起的策略来授予用户访问权限。策略可以使用任何类型的属性 ( 用户属性,资源属性,对象,环境属性等 )。要了解有关使用 ABAC 模式的更多信息,请参阅 [ABAC 模式](/docs/admin/authorization/abac/) +* **RBAC 模式** - 基于角色的访问控制 (RBAC) 是一种根据企业内个人用户的角色来调整对计算机或网络资源的访问的方法。在这种情况下,访问是单个用户执行特定任务 ( 例如查看,创建或修改文件 ) 的能力。要了解有关使用 RBAC 模式的更多信息,请参阅 [RBAC 模式](/docs/admin/authorization/rbac/) +*当指定 "RBAC"( 基于角色的访问控制 ) 使用 "rbac.authorization.k8s.io" API 组来驱动授权决定时,允许管理员通过 Kubernetes API 动态配置权限策略 . +.. *截至 1.6 RBAC 模式是测试版 . +.. *要启用 RBAC,请使用 `--authorization-mode=RBAC` 启动 apiserver. +* **Webhook 模式** - WebHook 是 HTTP 回调 : 发生事件时发生的 HTTP POST; 通过 HTTP POST 简单的事件通知 . 实施 WebHooks 的 Web 应用程序将在某些事情发生时向 URL 发送消息 . 要了解有关使用 Webhook 模式的更多信息,请参阅[Webhook 模式](/docs/admin/authorization/webhook/) +* **自定义模块** - 您可以创建使用 Kubernetes 的自定义模块 . 要了解更多信息,请参阅下面的**自定义模块**。 + +### 自定义模块 +可以相当容易地开发其他实现 ,APIserver 调用 Authorizer 接口: + +```go +type Authorizer interface { + Authorize(a Attributes) error +} +``` + +以确定是否允许每个 API 操作 . + +授权插件是实现此接口的模块 . 授权插件代码位于 `pkg/auth/authorizer/$MODULENAME` 中。 + +授权模块可以完全实现,也可以拨出远程授权服务。 授权模块可以实现自己的缓存,以减少具有相同或相似参数的重复授权调用的成本。 开发人员应该考虑缓存和撤销权限之间的交互。 + +#### 检查 API 访问 + +Kubernetes 将 `subjectaccessreviews.v1.authorization.k8s.io` 资源公开为允许外部访问 API 授权者决策的普通资源。 无论您选择使用哪个授权器,您都可以使用 `SubjectAccessReview` 发出一个 `POST`,就像 webhook 授权器的 `apis/authorization.k8s.io/v1/subjectaccessreviews` 端点一样,并回复一个响应。 例如: + + +```bash +kubectl create --v=8 -f - << __EOF__ +{ + "apiVersion": "authorization.k8s.io/v1", + "kind": "SubjectAccessReview", + "spec": { + "resourceAttributes": { + "namespace": "kittensandponies", + "verb": "get", + "group": "unicorn.example.org", + "resource": "pods" + }, + "user": "jane", + "group": [ + "group1", + "group2" + ], + "extra": { + "scopes": [ + "openid", + "profile" + ] + } + } +} +__EOF__ + +--- snip lots of output --- + +I0913 08:12:31.362873 27425 request.go:908] Response Body: {"kind":"SubjectAccessReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"resourceAttributes":{"namespace":"kittensandponies","verb":"GET","group":"unicorn.example.org","resource":"pods"},"user":"jane","group":["group1","group2"],"extra":{"scopes":["openid","profile"]}},"status":{"allowed":true}} +subjectaccessreview "" created +``` + +这对于调试访问问题非常有用,因为您可以使用此资源来确定授权者授予哪些访问权限。 + +## 为您的授权模块使用标志 + +您的策略中必须包含一个标志,以指出您的策略包含哪个授权模块 : + +可以使用以下标志 : + - `--authorization-mode=ABAC` 基于属性的访问控制 (ABAC) 模式允许您使用本地文件配置策略。 + - `--authorization-mode=RBAC` 基于角色的访问控制 (RBAC) 模式允许您使用 Kubernetes API 创建和存储策略 . + - `--authorization-mode=Webhook` WebHook 是一种 HTTP 回调模式,允许您使用远程 REST 管理授权。 + - `--authorization-mode=AlwaysDeny` 此标志阻止所有请求 . 仅使用此标志进行测试。 + - `--authorization-mode=AlwaysAllow` 此标志允许所有请求 . 只有在您不需要 API 请求授权的情况下才能使用此标志。 + +您可以选择多个授权模块,如果其中一种模式为 `AlwaysAllow`,则覆盖其他模式,并允许所有 API 请求。 + +## 版本控制 + +对于版本 1.2,配置了 kube-up.sh 创建的集群,以便任何请求都不需要授权。 + +从版本 1.3 开始,配置由 kube-up.sh 创建的集群,使得 ABAC 授权模块处于启用状态。但是,其输入文件最初设置为允许所有用户执行所有操作,集群管理员需要编辑该文件,或者配置不同的授权器来限制用户可以执行的操作。 + +{{% /capture %}} +{{% capture whatsnext %}} + +* 要学习有关身份验证的更多信息,请参阅**身份验证**[控制访问 Kubernetes API](docs/admin/access-the-api/)。 +* 要了解有关入学管理的更多信息,请参阅[使用 Admission 控制器](docs/admin/admission-controllers/)。 +* +{{% /capture %}} + + diff --git a/content/zh/docs/admin/high-availability/_index.md b/content/zh/docs/admin/high-availability/_index.md new file mode 100644 index 0000000000000..4d854b8daffba --- /dev/null +++ b/content/zh/docs/admin/high-availability/_index.md @@ -0,0 +1,214 @@ +--- +title: 构建高可用集群 +--- + + +## 简介 + + +本文描述了如何构建一个高可用(high-availability, HA)的 Kubernetes 集群。这是一个非常高级的主题。 + +对于仅希望使用 Kubernetes 进行试验的用户,推荐使用更简单的配置工具进行搭建,例如: +[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) 来运行 Kubernetes。 + +此外,当前在我们的端到端(e2e)测试环境中,没有对 Kubernetes 高可用的支持进行连续测试。我们将会增加这个连续测试项,但当前对单节点 master 的安装测试得更加严格。 + +{{< 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/{{< param "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 diff --git a/content/zh/docs/admin/ovs-networking.md b/content/zh/docs/admin/ovs-networking.md new file mode 100644 index 0000000000000..856148c0d84b2 --- /dev/null +++ b/content/zh/docs/admin/ovs-networking.md @@ -0,0 +1,22 @@ +--- +approvers: +- thockin +title: Kubernetes OpenVSwitch GRE/VxLAN 网络 +--- + +本文档介绍了如何使用 OpenVSwitch,在跨 nodes 的 pods 之间设置网络。 +隧道类型可以是 GRE 或者是 VxLAN。如需在网络内执行大规模隔离时,最好使用 VxLAN。 + +![OVS Networking](/images/docs/ovs-networking.png) + +Kubernetes 中 Vagrant 的设置如下: + +docker 网桥被 brctl 生成的 Linux 网桥(kbr0) 所代替,kbr0 是具有 256 个地址空间的子网。总的来说,node 会得到 10.244.x.0/24 的子网,docker 上配置使用的网桥会代替默认 docker0 的网桥。 + +另外,OVS 网桥创建(obr0),并将其作为端口添加到 kbr0 的网桥中。所有 OVS 网桥通过 GRE 隧道连接所有的 nodes。因此,每个 node 都有一个到其他 nodes 的出站 GRE 隧道。这个隧道没有必要是一个完整的网状物,但是越像网状结构越好。在网桥上开启 STP (生成树)模式以防止环路的发生。 + +路由规则允许任何 10.244.0.0/16 通过与隧道相连的 OVS 网桥到达目标。 + + + + diff --git a/content/zh/docs/concepts/_index.md b/content/zh/docs/concepts/_index.md index 6059a0544ef7f..59de4ca192596 100644 --- a/content/zh/docs/concepts/_index.md +++ b/content/zh/docs/concepts/_index.md @@ -28,7 +28,7 @@ weight: 40 -要使用 Kubernetes,你需要用 *Kubernetes API 对象* 来描述集群的*预期状态(desired state)* :包括你需要运行的应用或者负载,它们使用的镜像、副本数,以及所需网络和磁盘资源等等。你可以使用命令行工具 `kubectl` 来调用 Kubernetes API 创建对象,通过所创建的这些对象来配置预期状态。你也可以直接调用 Kubernetes API 和集群进行交互,设置或者修改预期状态。 +要使用 Kubernetes,你需要用 *Kubernetes API 对象* 来描述集群的 *预期状态(desired state)* :包括你需要运行的应用或者负载,它们使用的镜像、副本数,以及所需网络和磁盘资源等等。你可以使用命令行工具 `kubectl` 来调用 Kubernetes API 创建对象,通过所创建的这些对象来配置预期状态。你也可以直接调用 Kubernetes API 和集群进行交互,设置或者修改预期状态。 @@ -39,7 +39,7 @@ weight: 40 * **[kubelet](/docs/admin/kubelet/)**, which communicates with the Kubernetes Master. * **[kube-proxy](/docs/admin/kube-proxy/)**, a network proxy which reflects Kubernetes networking services on each node. --> -* **Kubernetes 主控组件(Master)** 包含三个进程,都运行在集群中的某个节上,通常这个节点被称为 master 节点。这些进程包括:[kube-apiserver](/docs/admin/kube-apiserver/)、[kube-controller-manager](/docs/admin/kube-controller-manager/)和[kube-scheduler](/docs/admin/kube-scheduler/)。 +* **Kubernetes 主控组件(Master)** 包含三个进程,都运行在集群中的某个节上,通常这个节点被称为 master 节点。这些进程包括:[kube-apiserver](/docs/admin/kube-apiserver/)、[kube-controller-manager](/docs/admin/kube-controller-manager/) 和 [kube-scheduler](/docs/admin/kube-scheduler/)。 * 集群中的每个非 master 节点都运行两个进程: * **[kubelet](/docs/admin/kubelet/)**,和 master 节点进行通信。 * **[kube-proxy](/docs/admin/kube-proxy/)**,一种网络代理,将 Kubernetes 的网络服务代理到每个节点上。 @@ -50,7 +50,7 @@ weight: 40 -Kubernetes 包含若干抽象用来表示系统状态,包括:已部署的容器化应用和负载、与它们相关的网络和磁盘资源以及有关集群正在运行的其他操作的信息。这些抽象使用 Kubernetes API 对象来表示。参阅 [Kubernetes对象概述](/docs/concepts/abstractions/overview/)以了解详细信息。 +Kubernetes 包含若干抽象用来表示系统状态,包括:已部署的容器化应用和负载、与它们相关的网络和磁盘资源以及有关集群正在运行的其他操作的信息。这些抽象使用 Kubernetes API 对象来表示。参阅 [Kubernetes 对象概述](/docs/concepts/abstractions/overview/)以了解详细信息。 @@ -77,7 +77,7 @@ Kubernetes 包含若干抽象用来表示系统状态,包括:已部署的容 -关于 Kubernetes 控制平面的各个部分,(如 Kubernetes 主控组件和 kubelet 进程,管理着 Kubernetes 如何与你的集群进行通信。控制平面维护着系统中所有的 Kubernetes 对象的状态记录,并且通过连续的控制循环来管理这些对象的状态。在任一的给定时间点,控制面的控制环都能响应集群中的变化,并且让系统中所有对象的实际状态与你提供的预期状态相匹配。 +关于 Kubernetes 控制平面的各个部分,(如 Kubernetes 主控组件和 kubelet 进程),管理着 Kubernetes 如何与你的集群进行通信。控制平面维护着系统中所有的 Kubernetes 对象的状态记录,并且通过连续的控制循环来管理这些对象的状态。在任意的给定时间点,控制面的控制环都能响应集群中的变化,并且让系统中所有对象的实际状态与你提供的预期状态相匹配。 @@ -93,7 +93,7 @@ Kubernetes master 节点负责维护集群的目标状态。当你要与 Kuberne -> "master" 是指管理集群状态的一组进程的集合。通常这些进程都跑在集群中一个单独的节点上,并且这个节点被称为 master 节点。master 节点也可以扩展副本数,来获取更好的性能及冗余。 +> "master" 是指管理集群状态的一组进程的集合。通常这些进程都跑在集群中一个单独的节点上,并且这个节点被称为 master 节点。master 节点也可以扩展副本数,来获取更好的可用性及冗余。 @@ -108,7 +108,7 @@ Kubernetes master 节点负责维护集群的目标状态。当你要与 Kuberne #### 对象元数据 -* [注释](/docs/concepts/overview/working-with-objects/annotations/) +* [注解](/docs/concepts/overview/working-with-objects/annotations/) {{% /capture %}} diff --git a/content/zh/docs/concepts/architecture/_index.md b/content/zh/docs/concepts/architecture/_index.md new file mode 100755 index 0000000000000..93d61ea5ff67e --- /dev/null +++ b/content/zh/docs/concepts/architecture/_index.md @@ -0,0 +1,11 @@ +--- +title: "Kubernetes 架构" +weight: 30 +--- + + \ No newline at end of file diff --git a/content/zh/docs/concepts/architecture/cloud-controller.md b/content/zh/docs/concepts/architecture/cloud-controller.md index efa9ee49db05c..77e36af2c1ded 100644 --- a/content/zh/docs/concepts/architecture/cloud-controller.md +++ b/content/zh/docs/concepts/architecture/cloud-controller.md @@ -1,175 +1,458 @@ -title: 云控制器管理器的基本概念 +--- +title: 云控制器管理器的基础概念 +content_template: templates/concept +weight: 30 +--- -## 云控制器管理器 + -云控制器管理器(CCM)这个概念创建的初衷是为了让特定的云服务供应商代码和Kubernetes核心相互独立演化。云控制器管理器与其他主要组件如Kubernetes控制器管理器,API服务器和调度程序同时运行。云控制器管理器也可以作为Kubernetes的插件启动,这种情况下,CCM运行在Kubernetes系统之上。 -云控制器管理器基于插件机制设计,允许新的云服务供应商通过插件轻松地与Kubernetes集成。目前已经有在Kubernetes上加入新的云服务供应商计划,并为云服务供应商提供从原先的旧模式迁移到新CCM模式的方案。 +{{% capture overview %}} + + + +云控制器管理器(cloud controller manager,CCM)这个概念 (不要与二进制文件混淆)创建的初衷是为了让特定的云服务供应商代码和 Kubernetes 核心相互独立演化。云控制器管理器与其他主要组件(如 Kubernetes 控制器管理器,API 服务器和调度程序)一起运行。它也可以作为 Kubernetes 的插件启动,在这种情况下,它会运行在 Kubernetes 之上。 + + + +云控制器管理器基于插件机制设计,允许新的云服务供应商通过插件轻松地与 Kubernetes 集成。目前已经有在 Kubernetes 上加入新的云服务供应商计划,并为云服务供应商提供从原先的旧模式迁移到新 CCM 模式的方案。 + + 本文讨论了云控制器管理器背后的概念,并提供了相关功能的详细信息。 -下面这张图描述了没有云控制器管理器的Kubernetes集群架构: + + +这是没有云控制器管理器的 Kubernetes 集群的架构: + + + +![没有云控制器管理器的 Kubernetes 架构](/images/docs/pre-ccm-arch.png) + +{{% /capture %}} + + +{{% capture body %}} + + -![无云控制器管理器的 K8s 集群架构](/images/docs/pre-ccm-arch.png) ## 设计 -在上图中,Kubernetes和云服务供应商通过几个不同的组件进行了集成,分别是: + + +在上图中,Kubernetes 和云服务供应商通过几个不同的组件进行了集成,分别是: + + * Kubelet * Kubernetes 控制管理器 -* Kubernetes API服务器 +* Kubernetes API 服务器 + + + +CCM 整合了前三个组件中的所有依赖于云的逻辑,以创建与云的单一集成点。CCM 的新架构如下所示: + + -而CCM整合了前三个组件中的所有依赖于云的逻辑,用来创建与云的单点集成。新架构如下图所示: +![含有云控制器管理器的 Kubernetes 架构](/images/docs/post-ccm-arch.png) -![有云控制器管理器的 K8s 集群架构](/images/docs/post-ccm-arch.png) + +## CCM 的组成部分 -## CCM的组件 + -CCM突破了Kubernetes控制器管理器(KCM)的一些功能,并将其作为一个独立的进程运行。具体而言,它打破了KCM中与云相关的控制器。KCM具有以下依赖于云的控制器引擎: +CCM 打破了 Kubernetes 控制器管理器(KCM)的一些功能,并将其作为一个单独的进程运行。具体来说,它打破了 KCM 中依赖于云的控制器。KCM 具有以下依赖于云的控制器: + + * 节点控制器 * 卷控制器 * 路由控制器 * 服务控制器 + + +在 1.9 版本中,CCM 运行前述列表中的以下控制器: -在1.8版本中,当前运行中的CCM从上面的列表中运行以下控制器: + * 节点控制器 * 路由控制器 * 服务控制器 -另外,它运行另一个名为 PersistentVolumeLabels Controller 的控制器。这个控制器负责对在GCP和AWS云里创建的PersistentVolumes的域(Zone)和区(Region)标签进行设置。 + + +此外,它还运行另一个名为 PersistentVolumeLabels Controller 的控制器,这个控制器负责在 GCP 和 AWS 云中创建的 PersistentVolumes 的域(zone)和区(region)标签进行设置。 + +{{< note >}} + + +注意卷控制器不属于 CCM,由于其中涉及到的复杂性和对现有供应商特定卷的逻辑抽象,因此决定了卷控制器不会被移动到 CCM 之中。 -**注意**:卷控制器被特意设计为CCM之外的一部分。由于其中涉及到的复杂性和对现有供应商特定卷的逻辑抽象,因此决定了卷控制器不会被移动到CCM之中。 +{{< /note >}} -原本计划使用CCM来支持卷的目的是为了引入FlexVolume卷来支持可插拔卷。然而,官方正在计划使用更具备竞争力的CSI来取代FlexVolume卷。 + -考虑到这些正在进行中的变化,我们决定暂时停止当前工作直至CSI准备就绪。 +使用 CCM 支持 volume 的最初计划是使用 Flex volume 来支持可插拔卷,但是现在正在计划一项名为 CSI 的项目以取代 Flex。 -云服务供应商工作组(wg-cloud-provider)正在开展相关工作,以实现通过CCM支持PersistentVolume的功能。详细信息请参见[kubernetes/kubernetes#52371](https://github.com/kubernetes/kubernetes/pull/52371)。 + -## CCM功能 +考虑到这些正在进行中的变化,在 CSI 准备就绪之前,我们决定停止当前的工作。 -CCM从Kubernetes组件中继承了与云服务供应商相关的功能。本节基于被CCM继承其功能的组件展开描述。 + + +## CCM 的功能 + + + +CCM 从依赖于云提供商的 Kubernetes 组件继承其功能,本节基于这些组件组织。 + + ### 1. Kubernetes 控制器管理器 -CCM的大部分功能都来自KCM。 如上一节所述,CCM运行以下控制引擎: + + +CCM 的大多数功能都来自 KCM,如上一节所述,CCM 运行以下控制器。 + + * 节点控制器 * 路由控制器 * 服务控制器 -* PersistentVolumeLabels控制器 +* PersistentVolumeLabels 控制器 + + #### 节点控制器 -节点控制器负责通过从云服务供应商获得有关在集群中运行的节点的信息来初始化节点。节点控制器执行以下功能: + -1.使用云特定域(Zone)/区(Region)标签初始化节点。 +节点控制器负责通过从云提供商获取有关在集群中运行的节点的信息来初始化节点,节点控制器执行以下功能: -1.使用特定于云的实例详细信息初始化节点,例如类型和大小。 + -1.获取节点的网络地址和主机名。 +1. 使用特定于云的域(zone)/区(region)标签初始化节点; +2. 使用特定于云的实例详细信息初始化节点,例如,类型和大小; +3. 获取节点的网络地址和主机名; +4. 如果节点无响应,请检查云以查看该节点是否已从云中删除。如果已从云中删除该节点,请删除 Kubernetes 节点对象。 -1.如果节点无响应,检查该节点是否已从云中删除。如果该节点已从云中删除,则删除Kubernetes节点对象。 + #### 路由控制器 -路由控制器负责为云配置正确的路由,以便Kubernetes集群中不同节点上的容器可以相互通信。路由控制器仅适用于Google Compute Engine平台。 + + +Route 控制器负责适当地配置云中的路由,以便 Kubernetes 集群中不同节点上的容器可以相互通信。route 控制器仅适用于 Google Compute Engine 群集。 + + #### 服务控制器 -服务控制器负责监听服务的创建、更新和删除事件。根据Kubernetes中各个服务的当前状态,它将配置云负载平衡器(如ELB或Google LB)以反映Kubernetes中的服务状态。此外,它还确保云负载均衡器的服务后端保持最新。 + + +服务控制器负责监听服务的创建、更新和删除事件。根据 Kubernetes 中各个服务的当前状态,它配置云负载均衡器(如 ELB 或 Google LB)以反映 Kubernetes 中的服务状态。此外,它还确保云负载均衡器的服务后端是最新的。 + + #### PersistentVolumeLabels 控制器 -PersistentVolumeLabels控制器在AWS的EBS卷、GCE的PD卷创建时申请标签,这使得用户不再需要手动设置这些卷标签。 + -这些标签对于pod的调度工作是非常重要的,因为这些卷只能在它们所在的域(Zone)/区(Region)内工作,因此所有使用这些卷的pod都必须要在同一个域/区中才能保证进行调度正常进行。 +PersistentVolumeLabels 控制器在创建 AWS EBS/GCE PD 卷时应用标签,这样就无需用户手动设置这些卷上的标签。 -PersistentVolumeLabels控制器是专门为CCM创建的; 也就是说,在CCM创建之前它是不存在的。这样做是为了将Kubernetes API服务器(它是一个许可控制器)中的PV标签逻辑移动到CCM。 它不在KCM上运行。 + +这些标签对于 pod 的调度至关重要,因为这些卷仅限于在它们所在的域(zone)/区(region)内工作,使用这些卷的任何 Pod 都需要在同一域(zone)/区(region)中进行调度。 + + + +PersistentVolumeLabels 控制器专门为 CCM 创建; 也就是说,在创建 CCM 之前它不存在。这样做是为了将 Kubernetes API 服务器(它是一个准入控制器)中的 PV 标记逻辑移动到 CCM,它不在 KCM 上运行。 + + + +### 2. Kubelet + + + +节点控制器包含 kubelet 中依赖于云的功能,在引入 CCM 之前,kubelet 负责使用特定于云的详细信息(如 IP 地址,域/区标签和实例类型信息)初始化节点。CCM 的引入已将此初始化操作从 kubelet 转移到 CCM 中。 + + + +在这个新模型中,kubelet 初始化一个没有特定于云的信息的节点。但是,它会为新创建的节点添加污点,使节点不可调度,直到 CCM 使用特定于云的信息初始化节点后,才会清除这种污点,便得该节点可被调度。 + + + +### 3. Kubernetes API 服务器 -Node控制器包含kubelet中依赖于云的功能。在系统引入CCM组件之前,是由kubelet采用包含云特定信息的方式对节点进行初始化,如IP地址、区(Region)/域(Zone)标签和实例类型信息;引入CCM之后,这部分的初始化操作就从kubelet转移到了CCM中。 + -在引入CCM后的新的模型中,kubelet采用不包含云特定信息的方式初始化一个节点。但是,它会为新创建的节点添加一个污点,使得该节点不可被立即调度,直到CCM使用包含云的特定信息初始化节点后,才会删除该污点,使得该节点可被调度。 +PersistentVolumeLabels 控制器将 Kubernetes API 服务器的依赖于云的功能移至 CCM,如前面部分所述。 -### 3. Kubernetes API服务器 + -PersistentVolumeLabels控制器将Kubernetes API服务器的依赖于云的功能移至CCM,如前面部分所述。 ## 插件机制 -云控制器管理器使用Go接口与外部对接从而实现功能扩展。具体来说,它使用了[这里](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go)定义的CloudProvider接口。 + -上面强调的四个共享控制器的实现,以及一些辅助设施(scaffolding)和共享的云服务供应商接口,将被保留在Kubernetes核心当中。但云服务供应商特有的实现将会建立在核心之外,并实现核心中定义的接口。 +云控制器管理器使用 Go 接口允许插入任何云的实现。具体来说,它使用[此处](https://github.com/kubernetes/cloud-provider/blob/9b77dc1c384685cb732b3025ed5689dd597a5971/cloud.go#L42-L62)定义的 CloudProvider 接口。 -有关开发插件的更多信息,请参阅 -[开发云控制器管理器](/docs/tasks/administrators-cluster/developing-cloud-controller-manager/)。 + + + +上面强调的四个共享控制器的实现,以及一些辅助设施(scaffolding)和共享的 cloudprovider 接口,将被保留在 Kubernetes 核心中。但特定于云提供商的实现将在核心之外构建,并实现核心中定义的接口。 + + + +有关开发插件的更多信息,请参阅[开发云控制器管理器](/docs/tasks/administer-cluster/developing-cloud-controller-manager/)。 + + ## 授权 -本节分解了CCM对各种API对象的访问,以执行其操作。 + + +本节分解了 CCM 执行其操作时各种 API 对象所需的访问权限。 + + ### 节点控制器 -节点控制器仅适用于节点对象。它需要完全访问权限来获取、列出、创建、更新、修补、监视和删除节点对象。 + + +Node 控制器仅适用于 Node 对象,它需要完全访问权限来获取、列出、创建、更新、修补、监视和删除 Node 对象。 + + + +v1/Node: -v1/Node: - Get - List - Create - Update - Patch - Watch +- Delete + + ### 路由控制器 -路由控制器监听节点对象的创建并配置合适的路由。它需要对节点对象的访问权限。 + + +路由控制器侦听 Node 对象创建并适当地配置路由,它需要访问 Node 对象。 + +v1/Node: -v1/Node: - Get + + ### 服务控制器 -服务控制器侦听服务对象创建、更新和删除事件,然后对这些服务的端点进行恰当的配置。 + + +服务控制器侦听 Service 对象创建、更新和删除事件,然后适当地为这些服务配置端点。 -要访问服务,它需要罗列和监控权限。要更新服务,它需要修补和更新权限。 + -要为服务设置端点,需要访问创建、列表、获取、监视和更新。 +要访问服务,它需要列表和监视访问权限。要更新服务,它需要修补和更新访问权限。 + + + +要为服务设置端点,需要访问 create、list、get、watch 和 update。 v1/Service: + - List - Get - Watch - Patch - Update + + ### PersistentVolumeLabels 控制器 -PersistentVolumeLabels控制器监听PersistentVolume(PV)创建事件并更新它们。该控制器需要访问列表、查看、获取和更新PV的权限。 + + +PersistentVolumeLabels 控制器侦听 PersistentVolume(PV)创建事件并更新它们,该控制器需要访问以获取和更新 PV。 v1/PersistentVolume: + - Get - List - Watch - Update + + ### 其它 -CCM核心的实现需要创建事件的权限,为了确保安全操作,需要创建ServiceAccounts的权限。 + + +CCM 核心的实现需要访问权限以创建事件,并且为了确保安全操作,它需要访问权限以创建服务账户。 v1/Event: + - Create - Patch - Update v1/ServiceAccount: + - Create -针对CCM的RBAC ClusterRole如下所示: + + + +针对 CCM 的 RBAC ClusterRole 看起来像这样: ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -233,17 +516,44 @@ rules: - update ``` + + + ## 供应商实施 -以下云服务供应商为自己的云部署了CCM。 + +以下云服务提供商已实现了 CCM: + + + +* [Digital Ocean](https://github.com/digitalocean/digitalocean-cloud-controller-manager) +* [Oracle](https://github.com/oracle/oci-cloud-controller-manager) +* [Azure](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/azure) +* [GCE](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/gce) +* [AWS](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/aws) + + ## 群集管理 -[这里](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)提供了配置和运行CCM的完整说明。 + + +[这里](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)提供了有关配置和运行 CCM 的完整说明。 + +{{% /capture %}} + diff --git a/content/zh/docs/concepts/architecture/master-node-communication.md b/content/zh/docs/concepts/architecture/master-node-communication.md index 45b2d08d5990d..9c117c2185bd9 100644 --- a/content/zh/docs/concepts/architecture/master-node-communication.md +++ b/content/zh/docs/concepts/architecture/master-node-communication.md @@ -40,7 +40,7 @@ Master 组件通过非安全(没有加密或认证)端口和集群的 apiser 从 master(apiserver)到集群有两种主要的通信路径。第一种是从 apiserver 到集群中每个节点上运行的 kubelet 进程。第二种是从 apiserver 通过它的代理功能到任何 node、pod 或者 service。 -### apiserver -> kubelet +## apiserver -> kubelet 从 apiserver 到 kubelet 的连接用于获取 pods 日志、连接(通过 kubectl)运行中的 pods,以及使用 kubelet 的端口转发功能。这些连接终止于 kubelet 的 HTTPS endpoint。 @@ -52,19 +52,19 @@ Master 组件通过非安全(没有加密或认证)端口和集群的 apiser 为了对这个连接进行认证,请使用 `--kubelet-certificate-authority` 标记给 apiserver 提供一个根证书捆绑,用于 kubelet 的服务证书。 -如果这样不可能,又要求避免在不可信的或公共的网络上进行连接,请在 apiserver 和 kubelet 之间使用 [SSH 隧道](/docs/concepts/architecture/master-node-communication/#ssh-tunnels)。 +如果这样不可能,又要求避免在不可信的或公共的网络上进行连接,请在 apiserver 和 kubelet 之间使用 [SSH 隧道](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)。 -最后,应该启用[Kubelet 用户认证和/或权限认证](/docs/admin/kubelet-authentication-authorization/)来保护 kubelet API。 +最后,应该启用 [Kubelet 用户认证和/或权限认证](/docs/admin/kubelet-authentication-authorization/)来保护 kubelet API。 -### apiserver -> nodes, pods, and services +## apiserver -> nodes, pods, and services -从 apiserver 到 node、pod或者service 的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。他们能够通过给API URL 中的 node、pod 或 service 名称添加前缀 `https:` 来运行在安全的 HTTPS 连接上。但他们即不会认证 HTTPS endpoint 提供的证书,也不会提供客户端证书。这样虽然连接是加密的,但它不会提供任何完整性保证。这些连接**目前还不能安全的**在不可信的或公共的网络上运行。 +从 apiserver 到 node、pod 或者 service 的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。他们能够通过给 API URL 中的 node、pod 或 service 名称添加前缀 `https:` 来运行在安全的 HTTPS 连接上。但他们即不会认证 HTTPS endpoint 提供的证书,也不会提供客户端证书。这样虽然连接是加密的,但它不会提供任何完整性保证。这些连接**目前还不能安全的**在不可信的或公共的网络上运行。 -### SSH 隧道 +## SSH 隧道 [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。 diff --git a/content/zh/docs/concepts/architecture/nodes.md b/content/zh/docs/concepts/architecture/nodes.md index 49971d1c54d6d..37b393714a885 100644 --- a/content/zh/docs/concepts/architecture/nodes.md +++ b/content/zh/docs/concepts/architecture/nodes.md @@ -61,9 +61,12 @@ redirect_from: | ---------------- | ---------------------------------------- | | `OutOfDisk` | `True` 表示 node 的空闲空间不足以用于添加新 pods, 否则为 `False` | | `Ready` | `True` 表示 node 是健康的并已经准备好接受 pods;`False` 表示 node 不健康而且不能接受 pods;`Unknown` 表示 node 控制器在最近 40 秒内没有收到 node 的消息 | -| `MemoryPressure` | `True` 表示 node 不存在内存压力 -- 即 node 内存用量低, 否则为 `False` | -| `DiskPressure` | `True` 表示 node 不存在磁盘压力 -- 即磁盘用量低, 否则为 `False` | - +| `MemoryPressure` | `True` 表示 node 存在内存压力 -- 即 node 内存用量低,否则为 `False` | +| `DiskPressure` | `True` 表示 node 存在磁盘压力 -- 即磁盘用量低,否则为 `False` | + Node 条件使用一个 JSON 对象表示。例如,下面的响应描述了一个健康的 node。 @@ -77,10 +80,10 @@ Node 条件使用一个 JSON 对象表示。例如,下面的响应描述了一 ``` -如果 Ready 条件处于状态 "Unknown" 或者 "False" 的时间超过了 `pod-eviction-timeout`(一个传递给 [kube-controller-manager](/docs/admin/kube-controller-manager/) 的参数),node 上的所有 Pods 都会被 Node 控制器计划删除。默认的删除超时时长为**5分钟**。某些情况下,当 node 不可访问时,apiserver 不能和其上的 kubelet 通信。删除 pods 的决定不能传达给 kubelet,直到它重新建立和 apiserver 的连接为止。与此同时,被计划删除的 pods 可能会继续在分区 node 上运行。 +如果 Ready 条件处于状态 "Unknown" 或者 "False" 的时间超过了 `pod-eviction-timeout`(一个传递给 [kube-controller-manager](/docs/admin/kube-controller-manager/) 的参数),node 上的所有 Pods 都会被 Node 控制器计划删除。默认的删除超时时长为**5 分钟**。某些情况下,当 node 不可访问时,apiserver 不能和其上的 kubelet 通信。删除 pods 的决定不能传达给 kubelet,直到它重新建立和 apiserver 的连接为止。与此同时,被计划删除的 pods 可能会继续在分区 node 上运行。 -在 1.5 版本之前的 Kubernetes 里,node 控制器会将不能访问的 pods 从 apiserver 中[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)。但在 1.5 或更高的版本里,在node 控制器确认这些 pods 已经在集群里停运行前不会强制删除它们。你可以看到这些处于 "Terminating" 或者 "Unknown" 状态的 pods 可能在无法访问的 node 上运行。为了防止 kubernetes 不能从底层基础设施中推断出一个 node 是否已经永久的离开了集群,集群管理员可能需要手动删除这个 node 对象。从 Kubernetes 删除 node 对象将导致 apiserver 删除 node 上所有运行的 Pod 对象并释放它们的名字。 +在 1.5 版本之前的 Kubernetes 里,node 控制器会将不能访问的 pods 从 apiserver 中[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)。但在 1.5 或更高的版本里,在 node 控制器确认这些 pods 已经在集群里停运行前不会强制删除它们。你可以看到这些处于 "Terminating" 或者 "Unknown" 状态的 pods 可能在无法访问的 node 上运行。为了防止 kubernetes 不能从底层基础设施中推断出一个 node 是否已经永久的离开了集群,集群管理员可能需要手动删除这个 node 对象。从 Kubernetes 删除 node 对象将导致 apiserver 删除 node 上所有运行的 Pod 对象并释放它们的名字。 ### 容量 @@ -117,7 +120,7 @@ Node 条件使用一个 JSON 对象表示。例如,下面的响应描述了一 Kubernetes 会在内部创一个 node 对象(象征 node),并基于 `metadata.name` 字段(我们假设 `metadata.name` 能够被解析)通过健康检查来验证 node。如果 node 可用,意即所有必要服务都已运行,它就符合了运行一个 pod 的条件;否则它将被所有的集群动作忽略直到变为可用。请注意,Kubernetes 将保存不可用 node 的对象,除非它被客户端显式的删除。Kubernetes 将持续检查 node 是否变的可用。 -当前,有3个组件同 Kubernetes node 接口交互:node 控制器、kubelet 和 kubectl。 +当前,有 3 个组件同 Kubernetes node 接口交互:node 控制器、kubelet 和 kubectl。 ### Node 控制器 @@ -141,13 +144,13 @@ Node 控制器在 node 的生命周期中扮演了多个角色。第一个是当 大部分情况下, node 控制器把删除频率限制在每秒 `--node-eviction-rate` 个(默认为 0.1)。这表示它在 10 秒钟内不会从超过一个 node 上删除 pods。 -当一个 availability zone 中的 node 变为不健康时,它的删除行为将发生改变。Node 控制器会同时检查 zone 中不健康(NodeReady 状态为 ConditionUnknown 或 ConditionFalse)的 nodes 的百分比。如果不健康 nodes 的部分超过 `--unhealthy-zone-threshold` (默认为 0.55),删除速率将会减小:如果集群较小(意即小于等于 `--large-cluster-size-threshold` 个 nodes - 默认为50),删除将会停止,否则删除速率将降为每秒 `--secondary-node-eviction-rate` 个(默认为 0.01)。在单个 availability zone 实施这些策略的原因是当一个 availability zone 可能从 master 分区时其它的仍然保持连接。如果你的集群没有跨越云服务商的多个 availability zones,那就只有一个 availability zone(整个集群)。 +当一个 availability zone 中的 node 变为不健康时,它的删除行为将发生改变。Node 控制器会同时检查 zone 中不健康(NodeReady 状态为 ConditionUnknown 或 ConditionFalse)的 nodes 的百分比。如果不健康 nodes 的部分超过 `--unhealthy-zone-threshold` (默认为 0.55),删除速率将会减小:如果集群较小(意即小于等于 `--large-cluster-size-threshold` 个 nodes - 默认为 50),删除将会停止,否则删除速率将降为每秒 `--secondary-node-eviction-rate` 个(默认为 0.01)。在单个 availability zone 实施这些策略的原因是当一个 availability zone 可能从 master 分区时其它的仍然保持连接。如果你的集群没有跨越云服务商的多个 availability zones,那就只有一个 availability zone(整个集群)。 在多个 availability zones 分布你的 nodes 的一个关键原因是当整个 zone 故障时,工作负载可以转移到健康的 zones。因此,如果一个 zone 中的所有 nodes 都不健康时,node 控制器会以正常的速率 `--node-eviction-rate` 删除。在所有的 zones 都不健康(也即集群中没有健康 node)的极端情况下,node 控制器将假设 master 的连接出了某些问题,它将停止所有删除动作直到一些连接恢复。 -从 Kubernetes 1.6 开始,NodeController 还负责删除运行在拥有 `NoExecute` taints 的 nodes 上的 pods,如果这些 pods 没有 tolerate 这些 taints。此外,作为一个默认禁用的 alpha 特性,NodeController 还负责根据 node 故障(例如 node 不可访问或没有 ready)添加 taints。请查看 [这个文档](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature)了解关于 `NoExecute` taints 和这个 alpha 特性。 +从 Kubernetes 1.6 开始,NodeController 还负责删除运行在拥有 `NoExecute` taints 的 nodes 上的 pods,如果这些 pods 没有 tolerate 这些 taints。此外,作为一个默认禁用的 alpha 特性,NodeController 还负责根据 node 故障(例如 node 不可访问或没有 ready)添加 taints。请查看[这个文档](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature)了解关于 `NoExecute` taints 和这个 alpha 特性。 ### Nodes 自注册 @@ -180,7 +183,7 @@ Node 控制器在 node 的生命周期中扮演了多个角色。第一个是当 如果管理员希望手动创建 node 对象,请设置 kubelet 标记 `--register-node=false`。 -管理员可以修改 node 资源(忽略 `--register-node` 设置)。修改包括在 node 上设置 labels及标记它为不可调度。 +管理员可以修改 node 资源(忽略 `--register-node` 设置)。修改包括在 node 上设置 labels 及标记它为不可调度。 Nodes 上的 labels 可以和 pods 的 node selectors 一起使用来控制调度,例如限制一个 pod 只能在一个符合要求的 nodes 子集上运行。 diff --git a/content/zh/docs/concepts/cluster-administration/_index.md b/content/zh/docs/concepts/cluster-administration/_index.md new file mode 100644 index 0000000000000..9ec54aaf96dc8 --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/_index.md @@ -0,0 +1,11 @@ +--- +title: "计算、存储和网络扩展" +weight: 30 +--- + + \ No newline at end of file diff --git a/content/zh/docs/concepts/cluster-administration/addons.md b/content/zh/docs/concepts/cluster-administration/addons.md index 1ddac950f1f64..659f2874476e8 100644 --- a/content/zh/docs/concepts/cluster-administration/addons.md +++ b/content/zh/docs/concepts/cluster-administration/addons.md @@ -24,7 +24,7 @@ Add-ons 扩展了 Kubernetes 的功能。 * [Cilium](https://github.com/cilium/cilium) 是一个 L3 网络和网络策略插件, 能够透明的实施 HTTP/API/L7 策略。 同时支持路由(routing)和叠加/封装( overlay/encapsulation)模式。 * [Contiv](http://contiv.github.io) 为多种用例提供可配置网络(使用 BGP 的原生 L3,使用 vxlan 的 overlay,经典 L2 和 Cisco-SDN/ACI)和丰富的策略框架。Contiv 项目完全[开源](http://github.com/contiv)。[安装工具](http://github.com/contiv/install)同时提供基于和不基于 kubeadm 的安装选项。 * [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel.yml) 是一个可以用于 Kubernetes 的 overlay 网络提供者。 -* [Romana](http://romana.io) 是一个 pod 网络的层 3 解决方案,并且支持 [NetworkPolicy API](/docs/concepts/services-networking/network-policies/)。Kubeadm add-on 安装细节可以在[这里](https://github.com/romana/romana/tree/master/containerize)找到。 +* [Romana](http://romana.io) 是一个 pod 网络的层 3 解决方案,并且支持 [NetworkPolicy API](/docs/concepts/services-networking/network-policies/)。Kubeadm add-on 安装细节可以在[这里](https://github.com/romana/romana/tree/master/containerize)找到。 * [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) 提供了在网络分组两端参与工作的网络和网络策略,并且不需要额外的数据库。 * [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) 使 Kubernetes 无缝连接到一种 CNI 插件,例如:Flannel、Calico、Canal、Romana 或者 Weave。 @@ -33,7 +33,7 @@ Add-ons 扩展了 Kubernetes 的功能。 * [Dashboard](https://github.com/kubernetes/dashboard#kubernetes-dashboard) 是一个 Kubernetes 的 web 控制台界面。 -* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s) 是一个图形化工具,用于查看你的 containers、 pods、services等。 请和一个 [Weave Cloud account](https://cloud.weave.works/) 一起使用,或者自己运行 UI。 +* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s) 是一个图形化工具,用于查看你的 containers、 pods、services 等。 请和一个 [Weave Cloud account](https://cloud.weave.works/) 一起使用,或者自己运行 UI。 ## 遗留 Add-ons diff --git a/content/zh/docs/concepts/cluster-administration/certificates.md b/content/zh/docs/concepts/cluster-administration/certificates.md index c70f17b7431a7..b8347a49befc6 100644 --- a/content/zh/docs/concepts/cluster-administration/certificates.md +++ b/content/zh/docs/concepts/cluster-administration/certificates.md @@ -17,7 +17,7 @@ title: 证书 `cluster/saltbase/salt/generate-cert/make-ca-cert.sh`。 执行该脚本时需传入两个参数。 第一个参数为 API 服务器的 IP 地址,第二个参数为对象的候补名称列表, -形如 `IP: 或 DNS:`。 +形如 `IP: 或 DNS:`。 脚本生成三个文件: `ca.crt`、`server.crt` 和 `server.key`。 @@ -44,7 +44,7 @@ title: 证书 ./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass 1. 生成服务器证书和密钥。 参数 `--subject-alt-name` 设置了访问 API 服务器时可能使用的 IP 和 DNS 名称。 `MASTER_CLUSTER_IP` - 通常为 `--service-cluster-ip-range` 参数中指定的服务 CIDR 的 首个 IP 地址,`--service-cluster-ip-range`同时用于 + 通常为 `--service-cluster-ip-range` 参数中指定的服务 CIDR 的 首个 IP 地址,`--service-cluster-ip-range` 同时用于 API 服务器和控制器管理器组件。 `--days` 参数用于设置证书的有效期限。 下面的示例还假设用户使用 `cluster.local` 作为默认的 DNS 域名。 @@ -78,7 +78,7 @@ title: 证书 openssl genrsa -out server.key 2048 1. 创建用于生成证书签名请求(CSR)的配置文件。 - 确保在将其保存至文件(如`csr.conf`)之前将尖括号标记的值(如``) + 确保在将其保存至文件(如 `csr.conf`)之前将尖括号标记的值(如 ``) 替换为你想使用的真实值。 注意:`MASTER_CLUSTER_IP` 是前面小节中描述的 API 服务器的服务集群 IP (service cluster IP)。 下面的示例也假设用户使用 `cluster.local` 作为默认的 DNS 域名。 diff --git a/content/zh/docs/concepts/cluster-administration/cloud-providers.md b/content/zh/docs/concepts/cluster-administration/cloud-providers.md index 2b9721d3fe4ba..71545ed669c96 100644 --- a/content/zh/docs/concepts/cluster-administration/cloud-providers.md +++ b/content/zh/docs/concepts/cluster-administration/cloud-providers.md @@ -105,5 +105,3 @@ Kubernetes 利用 OpenStack 服务目录对它知道如何使用的服务进行 bs-version=v2 ``` {{% /capture %}} - - diff --git a/content/zh/docs/concepts/cluster-administration/cluster-administration-overview.md b/content/zh/docs/concepts/cluster-administration/cluster-administration-overview.md index 60178404269b4..ad53aab637296 100644 --- a/content/zh/docs/concepts/cluster-administration/cluster-administration-overview.md +++ b/content/zh/docs/concepts/cluster-administration/cluster-administration-overview.md @@ -9,7 +9,7 @@ content_template: templates/concept {{% capture overview %}} -集群管理概述面向任何创建和管理 Kubernetes 集群的读者人群。我们假设你对 [用户指南](/docs/user-guide/)中的概念有一些熟悉。 +集群管理概述面向任何创建和管理 Kubernetes 集群的读者人群。我们假设你对[用户指南](/docs/user-guide/)中的概念有一些熟悉。 {{% /capture %}} {{% capture body %}} @@ -24,8 +24,8 @@ content_template: templates/concept - 你是打算在你的电脑上尝试 Kubernetes,还是要构建一个高可用的多节点集群?请选择最适合你需求的发行版。 - **如果你正在设计一个高可用集群**,请了解[在多个 zones 中配置集群](/docs/admin/multi-cluster)。 - - 你的集群是在**本地**还是**云(IaaS)**上?Kubernetes 不能直接支持混合集群。作为代替,你可以建立多个集群。 - - **如果你在本地配置 Kubernetes**,需要考虑哪种[网络模型](/docs/admin/networking)最适合。 + - 你的集群是在**本地**还是**云(IaaS)**上? Kubernetes 不能直接支持混合集群。作为代替,你可以建立多个集群。 + - **如果你在本地配置 Kubernetes**,需要考虑哪种[网络模型](/docs/admin/networking)最适合。一种自定义网络的选项是 [*OpenVSwitch GRE/VxLAN 网络*](/docs/admin/ovs-networking/),它使用 OpenVSwitch 在跨 Kubernetes 节点的 pods 之间建立起网络。 - 你的 Kubernetes 在 **裸金属硬件** 还是 **虚拟机(VMs)**上运行? - 你**只想运行一个集群**,还是打算**活动开发 Kubernetes 项目代码**?如果是后者,请选择一个活动开发的发行版。某些发行版只提供二进制发布版,但提供更多的选择。 - 让你自己熟悉运行一个集群所需的[组件](/docs/admin/cluster-components) 。 @@ -49,10 +49,10 @@ content_template: templates/concept * [Kubernetes 容器环境](/docs/concepts/containers/container-environment-variables/) 描述了 Kubernetes 节点上由 Kubelet 管理的容器的环境。 -* [控制到 Kubernetes API 的访问](/docs/admin/accessing-the-api) 描述了如何为用户和 service accounts 建立权限许可. +* [控制到 Kubernetes API 的访问](/docs/admin/accessing-the-api)描述了如何为用户和 service accounts 建立权限许可。 -* [用户认证](/docs/admin/authentication) 阐述了 Kubernetes 中的认证功能,包括许多认证选项。 +* [用户认证](/docs/admin/authentication)阐述了 Kubernetes 中的认证功能,包括许多认证选项。 * [授权](/docs/admin/authorization)从认证中分离出来,用于控制如何处理 HTTP 请求。 @@ -64,7 +64,7 @@ content_template: templates/concept * [在 Kubernetes Cluster 中使用 Sysctls](/docs/concepts/cluster-administration/sysctl-cluster/) 描述了管理员如何使用 `sysctl` 命令行工具来设置内核参数。 -* [审计](/docs/tasks/debug-application-cluster/audit/) 描述了如何与 Kubernetes 的审计日志交互。 +* [审计](/docs/tasks/debug-application-cluster/audit/)描述了如何与 Kubernetes 的审计日志交互。 ### 保护 kubelet @@ -77,11 +77,9 @@ content_template: templates/concept ## 可选集群服务 -* [DNS 与 SkyDNS 集成](/docs/concepts/services-networking/dns-pod-service/)描述了如何将一个 DNS 名解析到一个Kubernetes service。 +* [DNS 与 SkyDNS 集成](/docs/concepts/services-networking/dns-pod-service/)描述了如何将一个 DNS 名解析到一个 Kubernetes service。 -* [记录和监控集群活动](/docs/concepts/cluster-administration/logging/) 阐述了Kubernetes 的日志如何工作以及怎样实现。 +* [记录和监控集群活动](/docs/concepts/cluster-administration/logging/)阐述了 Kubernetes 的日志如何工作以及怎样实现。 {{% /capture %}} - - diff --git a/content/zh/docs/concepts/cluster-administration/controller-metrics.md b/content/zh/docs/concepts/cluster-administration/controller-metrics.md new file mode 100644 index 0000000000000..85a46101ffea7 --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/controller-metrics.md @@ -0,0 +1,82 @@ +--- +title: 控制器管理器指标 +content_template: templates/concept +weight: 100 +--- + + + +{{% capture overview %}} + + + +控制器管理器指标为控制器管理器的性能和健康提供了重要的观测手段。 + +{{% /capture %}} + +{{% capture body %}} + + + +## 什么是控制器管理器度量 + +控制器管理器指标为控制器管理器的性能和健康提供了重要的观测手段。 +这些度量包括常见的 Go 语言运行时度量,比如 go_routine 计数,以及控制器特定的度量,比如 etcd 请求延迟或 云提供商(AWS、GCE、OpenStack)的 API 延迟,这些参数可以用来测量集群的健康状况。 + +从 Kubernetes 1.7 版本开始,详细的云提供商指标可用于 GCE、AWS、Vsphere 和 OpenStack 的存储操作。 +这些度量可用于监视持久卷操作的健康状况。 + +例如,在 GCE 中这些指标叫做: + +``` +cloudprovider_gce_api_request_duration_seconds { request = "instance_list"} +cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"} +cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"} +cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"} +cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"} +cloudprovider_gce_api_request_duration_seconds { request = "list_disk"} +``` + + + +## 配置 + +在集群中,控制器管理器指标可从它所在的主机上的 `http://localhost:10252/metrics` 中获得。 + +这些指标是以 [prometheus 格式](https://prometheus.io/docs/instrumenting/exposition_formats/) 发出的,是人类可读的。 + +在生产环境中,您可能想配置 prometheus 或其他一些指标收集工具,以定期收集这些指标数据,并将它们应用到某种时间序列数据库中。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/cluster-administration/kubelet-garbage-collection.md b/content/zh/docs/concepts/cluster-administration/kubelet-garbage-collection.md new file mode 100644 index 0000000000000..6947c16f7d4ce --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/kubelet-garbage-collection.md @@ -0,0 +1,261 @@ +--- +title: 配置 kubelet 垃圾回收策略 +content_template: templates/concept +weight: 70 +--- + + + +{{% capture overview %}} + +垃圾回收是 kubelet 的一个有用功能,它将清理未使用的镜像和容器。 + + + +Kubelet 将每分钟对容器执行一次垃圾回收,每五分钟对镜像执行一次垃圾回收。 + + + +不建议使用外部垃圾收集工具,因为这些工具可能会删除原本期望存在的容器进而破坏 kubelet 的行为。 + + + +{{% /capture %}} + + +{{% capture body %}} + +## 镜像回收 + + + +Kubernetes 借助于 cadvisor 通过 imageManager 来管理所有镜像的生命周期。 + + + +镜像垃圾回收策略只考虑两个因素:`HighThresholdPercent` 和 `LowThresholdPercent`。 + + + +磁盘使用率超过上限阈值(HighThresholdPercent)将触发垃圾回收。 + + + +垃圾回收将删除最近最少使用的镜像,直到磁盘使用率满足下限阈值(LowThresholdPercent)。 + + + +## 容器回收 + + + +容器垃圾回收策略考虑三个用户定义变量。 + + + +`MinAge` 是容器可以被执行垃圾回收的最小年龄。 + + + +`MaxPerPodContainer` 是每个 pod 内允许存在的死亡容器的最大数量。 + + + +`MaxContainers` 是全部死亡容器的最大数量。 + + + +可以分别独立地通过将 `MinAge` 设置为 0,以及将 `MaxPerPodContainer` 和 `MaxContainers` 设置为小于 0 来禁用这些变量。 + + + +Kubelet 将处理无法辨识的、已删除的以及超出前面提到的参数所设置范围的容器。最老的容器通常会先被移除。 + + + +`MaxPerPodContainer` 和 `MaxContainer` 在某些场景下可能会存在冲突,例如在保证每个 pod 内死亡容器的最大数量(`MaxPerPodContainer`)的条件下可能会超过允许存在的全部死亡容器的最大数量(`MaxContainer`)。 + + + +`MaxPerPodContainer` 在这种情况下会被进行调整:最坏的情况是将 `MaxPerPodContainer` 降级为 1,并驱逐最老的容器。 + + + +此外,pod 内已经被删除的容器一旦年龄超过 `MinAge` 就会被清理。 + + + +不被 kubelet 管理的容器不受容器垃圾回收的约束。 + + + +## 用户配置 + + + +用户可以使用以下 kubelet 参数调整相关阈值来优化镜像垃圾回收: + + + + + +1. `image-gc-high-threshold`,触发镜像垃圾回收的磁盘使用率百分比。默认值为 85%。 + +2. `image-gc-low-threshold`,镜像垃圾回收试图释放资源后达到的磁盘使用率百分比。默认值为 80%。 + +我们还允许用户通过以下 kubelet 参数自定义垃圾收集策略: + + + + + +1. `minimum-container-ttl-duration`,完成的容器在被垃圾回收之前的最小年龄,默认是 0 分钟,这意味着每个完成的容器都会被执行垃圾回收。 + +2. `maximum-dead-containers-per-container`,每个容器要保留的旧实例的最大数量。默认值为 1。 + +3. `maximum-dead-containers`,要全局保留的旧容器实例的最大数量。默认值是 -1,这意味着没有全局限制。 + +容器可能会在其效用过期之前被垃圾回收。这些容器可能包含日志和其他对故障诊断有用的数据。 + + + +强烈建议为 `maximum-dead-containers-per-container` 设置一个足够大的值,以便每个预期容器至少保留一个死亡容器。 + + + +由于同样的原因,`maximum-dead-containers` 也建议使用一个足够大的值。 + + + +查阅 [这个问题](https://github.com/kubernetes/kubernetes/issues/13287) 获取更多细节。 + + + +## 弃用 + + + +这篇文档中的一些 kubelet 垃圾收集(Garbage Collection)功能将在未来被 kubelet 驱逐回收(eviction)所替代。 + + + +包括: + +| 现存参数 | 新参数 | 解释 | +| ------------- | -------- | --------- | +| `--image-gc-high-threshold` | `--eviction-hard` 或 `--eviction-soft` | 现存的驱逐回收信号可以触发镜像垃圾回收 | +| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | 驱逐回收实现相同行为 | +| `--maximum-dead-containers` | | 一旦旧日志存储在容器上下文之外,就会被弃用 | +| `--maximum-dead-containers-per-container` | | 一旦旧日志存储在容器上下文之外,就会被弃用 | +| `--minimum-container-ttl-duration` | | 一旦旧日志存储在容器上下文之外,就会被弃用 | +| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | 驱逐回收将磁盘阈值泛化到其他资源 | +| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | 驱逐回收将磁盘压力转换到其他资源 | + + + +{{% /capture %}} + +{{% capture whatsnext %}} + +查阅 [配置驱逐回收资源的策略](/docs/tasks/administer-cluster/out-of-resource/) 获取更多细节。 + + + +{{% /capture %}} diff --git a/content/zh/docs/concepts/cluster-administration/logging.md b/content/zh/docs/concepts/cluster-administration/logging.md new file mode 100755 index 0000000000000..be577dfb78221 --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/logging.md @@ -0,0 +1,460 @@ +--- +reviewers: +- piosz +- x13n +title: 日志架构 +content_template: templates/concept +weight: 60 +--- + +{{% capture overview %}} + + +应用和系统日志可以让您了解集群内部的运行状况。日志对调试问题和监控集群活动非常有用。大部分现代化应用都有某种日志记录机制;同样地,大多数容器引擎也被设计成支持某种日志记录机制。针对容器化应用,最简单且受欢迎的日志记录方式就是写入标准输出和标准错误流。 + + +但是,由容器引擎或 runtime 提供的原生功能通常不足以满足完整的日志记录方案。例如,如果发生容器崩溃、pod 被逐出或节点宕机等情况,您仍然想访问到应用日志。因此,日志应该具有独立的存储和生命周期,与节点、pod 或容器的生命周期相独立。这个概念叫 _集群级的日志_ 。集群级日志方案需要一个独立的后台来存储、分析和查询日志。Kubernetes 没有为日志数据提供原生存储方案,但是您可以集成许多现有的日志解决方案到 Kubernetes 集群中。 + +{{% /capture %}} + +{{% capture body %}} + + +集群级日志架构假定在集群内部或者外部有一个日志后台。如果您对集群级日志不感兴趣,您仍会发现关于如何在节点上存储和处理日志的描述对您是有用的。 + + +## Kubernetes 中的基本日志记录 + +本节,您会看到一个kubernetes 中生成基本日志的例子,该例子中数据被写入到标准输出。 +这里通过一个特定的 [pod 规约](/examples/debug/counter-pod.yaml) 演示创建一个容器,并令该容器每秒钟向标准输出写入数据。 + +{{< codenew file="debug/counter-pod.yaml" >}} + + +用下面的命令运行 pod: + +```shell +$ kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml +pod/counter created +``` + + +使用 `kubectl logs` 命令获取日志: + +```shell +$ kubectl logs counter +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + + +一旦发生容器崩溃,您可以使用命令 `kubectl logs` 和参数 `--previous` 检索之前的容器日志。 +如果 pod 中有多个容器,您应该向该命令附加一个容器名以访问对应容器的日志。 +详见 [`kubectl logs` 文档](/docs/reference/generated/kubectl/kubectl-commands#logs)。 + + +## 节点级日志记录 + +![Node level logging](/images/docs/user-guide/logging/logging-node-level.png) + + +容器化应用写入 `stdout` 和 `stderr` 的任何数据,都会被容器引擎捕获并被重定向到某个位置。 +例如,Docker 容器引擎将这两个输出流重定向到某个 [日志驱动](https://docs.docker.com/engine/admin/logging/overview) , +该日志驱动在 Kubernetes 中配置为以 json 格式写入文件。 + + +{{< note >}} +Docker json 日志驱动将日志的每一行当作一条独立的消息。该日志驱动不直接支持多行消息。您需要在日志代理级别或更高级别处理多行消息。 +{{< /note >}} + + +默认情况下,如果容器重启,kubelet 会保留被终止的容器日志。 +如果 pod 在工作节点被驱逐,该 pod 中所有的容器也会被驱逐,包括容器日志。 + + +节点级日志记录中,需要重点考虑实现日志的轮转,以此来保证日志不会消耗节点上所有的可用空间。 +Kubernetes 当前并不负责轮转日志,而是通过部署工具建立一个解决问题的方案。 +例如,在 Kubernetes 集群中,用 `kube-up.sh` 部署一个每小时运行的工具 [`logrotate`](https://linux.die.net/man/8/logrotate)。 +您也可以设置容器 runtime 来自动地轮转应用日志,比如使用 Docker 的 `log-opt` 选项。 +在 `kube-up.sh` 脚本中,使用后一种方式来处理 GCP 上的 COS 镜像,而使用前一种方式来处理其他环境。 +这两种方式,默认日志超过 10MB 大小时都会触发日志轮转。 + + +例如,您可以找到关于 `kube-up.sh` 为 GCP 环境的 COS 镜像设置日志的详细信息, +相应的脚本在 [这里][cosConfigureHelper]。 + + +当运行 [`kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs) 时, +节点上的 kubelet 处理该请求并直接读取日志文件,同时在响应中返回日志文件内容。 + +{{< note >}} + +当前,如果有其他系统机制执行日志轮转,那么 `kubectl logs` 仅可查询到最新的日志内容。 +比如,一个 10MB 大小的文件,通过`logrotate` 执行轮转后生成两个文件,一个 10MB 大小,一个为空,所以 `kubectl logs` 将返回空。 + +[cosConfigureHelper]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch">}}/cluster/gce/gci/configure-helper.sh +{{< /note >}} + + +### 系统组件日志 + +有两种类型的系统组件,运行在容器中的和未运行在容器中的。例如: + + +* 运行在容器中的 Kubernetes 调度器和 kube-proxy。 +* 未运行在容器中的 kubelet 和容器 runtime,比如 Docker。 + + +在使用 systemd 机制的服务器上,kubelet 和容器 runtime 写入日志到 journald。 +如果没有 systemd,他们写入日志到 `/var/log` 目录的 `.log` 文件。 +容器中的系统组件通常将日志写到 `/var/log` 目录,绕过了默认的日志机制。他们使用 [glog][glog] 日志库。 +您可以在[日志开发文档](https://git.k8s.io/community/contributors/devel/logging.md)找到这些组件的日志告警级别协议。 + + +和容器日志类似,`/var/log` 目录中的系统组件日志也应该被轮转。 +通过脚本 `kube-up.sh` 启动的 Kubernetes 集群中,日志被工具 `logrotate` 执行每日轮转,或者日志大小超过 100MB 时触发轮转。 + +[glog]: https://godoc.org/github.com/golang/glog + + +## 集群级别日志架构 + + +虽然 Kubernetes 并未提供原生的集群级记录日志方案,但是您可以考虑几种常见的方式。以下是一些选项: + +* 使用运行在各个节点上的节点级日志代理。 +* 在应用程序的 pod 中,包含专门记录日志的 sidecar 容器。 +* 在应用程序中将日志直接推送到后台。 + + +### 使用节点级日志代理 + +![Using a node level logging agent](/images/docs/user-guide/logging/logging-with-node-agent.png) + + +您可以在每个节点上使用 _节点级的日志代理_ 来实现集群级日志记录。 +日志代理是专门的工具,它会暴露出日志或将日志推送到后台。 +通常来说,日志代理是一个容器,这个容器可以访问这个节点上所有应用容器的日志目录。 + + +因为日志代理必须在每个节点上运行,所以通常的实现方式为,DaemonSet 副本、manifest pod 或者专用于本地的进程。 +但是后两种方式已被弃用并且不被推荐。 + + +对于 Kubernetes 集群来说,使用节点级的日志代理是最常用和被推荐的方式,因为在每个节点上仅创建一个代理,并且不需要对节点上的应用做修改。 +但是,节点级的日志 _仅适用于应用程序的标准输出和标准错误输出_。 + + +Kubernetes 并不指定日志代理,但是有两个可选的日志代理与 Kubernetes 发行版一起发布。 +[Stackdriver 日志](/docs/user-guide/logging/stackdriver) 适用于 Google Cloud Platform,和 [Elasticsearch](/docs/user-guide/logging/elasticsearch)。 +您可以在专门的文档中找到更多的信息和说明。两者都使用 [fluentd](http://www.fluentd.org/) 与自定义配置作为节点上的代理。 + + +### 使用 sidecar 容器和日志代理 + + +您可以通过以下方式之一使用 sidecar 容器: + + +* sidecar 容器将应用程序日志传送到自己的标准输出。 +* sidecar 容器运行一个日志代理,配置该日志代理以便从应用容器收集日志。 + + +#### 传输数据流的 sidecar 容器 + + +利用 sidecar 容器向自己的 `stdout` 和 `stderr` 传输流的方式,您就可以利用每个节点上的 kubelet 和日志代理来处理日志。 +sidecar 容器从文件,socket 或 journald 读取日志。每个 sidecar 容器打印其自己的 `stdout` 和 `stderr` 流。 + + +这种方式允许您分离出不同的日志流,这些日志流来自您应用的不同功能,其中一些可能缺乏对写入 `stdout` 和 `stderr` 的支持。 +重定向背后的逻辑很小,所以不会是很严重的开销。 +除此之外,因为 kubelet 处理 `stdout` 和 `stderr`,所以您照样可以使用 `kubectl logs` 工具。 + + +考虑接下来的例子。pod 的容器向两个文件写不同格式的日志,下面是这个 pod 的配置文件: + +{{< codenew file="admin/logging/two-files-counter-pod.yaml" >}} + + +在同一个日志流中有两种不同格式的日志条目,这有点混乱,即使您试图重定向它们到容器的 `stdout` 流。 +取而代之的是,您可以引入两个 sidecar 容器。 +每一个 sidecar 容器可以从共享卷跟踪特定的日志文件,并重定向文件内容到各自的 `stdout` 流。 + + +这是运行两个 sidecar 容器的 pod 文件。 + +{{< codenew file="admin/logging/two-files-counter-pod-streaming-sidecar.yaml" >}} + + +现在当您运行这个 pod 时,您可以分别地访问每一个日志流,运行如下命令: + +```shell +$ kubectl logs counter count-log-1 +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +```shell +$ kubectl logs counter count-log-2 +Mon Jan 1 00:00:00 UTC 2001 INFO 0 +Mon Jan 1 00:00:01 UTC 2001 INFO 1 +Mon Jan 1 00:00:02 UTC 2001 INFO 2 +... +``` + + +无需深入配置,集群中的节点级代理即可自动地收集流日志。如果您愿意,您可以配置代理程序来解析源容器的日志行。 + + +注意,尽管 CPU 和内存使用率都很低(以多个 cpu millicores 指标排序或者按 memory 的兆字节排序), +向文件写日志然后输出到 `stdout` 流仍然会成倍地增加磁盘使用率。 +如果您的应用向单一文件写日志,通常最好设置 `/dev/stdout` 作为目标路径,而不是使用流式的 sidecar 容器方式。 + + +应用本身如果不具备轮转日志文件的功能,可以通过 sidecar 容器实现。 +该方式的 [例子](https://github.com/samsung-cnct/logrotate) 是运行一个定期轮转日志的容器。 +然而,还是推荐直接使用 `stdout` 和 `stderr`,将日志的轮转和保留策略交给 kubelet。 + + +### 具有日志代理功能的 sidecar 容器 + +![Sidecar container with a logging agent](/images/docs/user-guide/logging/logging-with-sidecar-agent.png) + + +如果节点级的日志代理对您的环境来说不够灵活,您可以在 sidecar 容器中创建一个独立的、专门为您的应用而配置的日志代理。 + + +{{< note >}} +在 sidecar 容器中使用日志代理会导致严重的资源损耗。此外,您不能使用 `kubectl logs` 命令访问日志,因为日志并没有被 kubelet 管理。 +{{< /note >}} + + +例如,您可以使用 [Stackdriver](/docs/tasks/debug-application-cluster/logging-stackdriver/),它用 fluentd 作为日志代理。 +这是实现此种方式的两个配置文件。 +第一个文件包含配置 fluentd 的 [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/)。 + +{{< codenew file="admin/logging/fluentd-sidecar-config.yaml" >}} + + +{{< note >}} +fluentd 的配置文件已经超出了本文的讨论范畴。 +有关配置 fluentd 的更多信息,请见 [官方 fluentd 文档](http://docs.fluentd.org/)。 +{{< /note >}} + + +第二个文件描述了运行 fluentd sidecar 容器的 pod 。flutend 通过 pod 的挂载卷获取它的配置数据。 + +{{< codenew file="admin/logging/two-files-counter-pod-agent-sidecar.yaml" >}} + + +一段时间后,您可以在 Stackdriver 界面看到日志消息。 + + +记住,这只是一个例子,事实上您可以用任何一个日志代理替换 fluentd ,并从应用容器中读取任何资源。 + + + +### 从应用中直接暴露日志目录 + +![Exposing logs directly from the application](/images/docs/user-guide/logging/logging-from-application.png) + + +通过暴露或推送每个应用的日志,您可以实现集群级日志记录;然而,这种日志记录机制的实现已超出 Kubernetes 的范围。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/cluster-administration/manage-deployment.md b/content/zh/docs/concepts/cluster-administration/manage-deployment.md new file mode 100644 index 0000000000000..c8589e45f880a --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/manage-deployment.md @@ -0,0 +1,629 @@ +--- +reviewers: +- bgrant0607 +- janetkuo +- mikedanese +title: 管理资源 +content_template: templates/concept +weight: 40 +--- + + +{{% capture overview %}} + + +您已经部署了应用并通过服务暴露它。然后呢?Kubernetes 提供了一些工具来帮助管理您的应用部署,包括缩扩容和更新。我们将更深入讨论的特性包括[配置文件](/docs/concepts/configuration/overview/)和[标签](/docs/concepts/overview/working-with-objects/labels/)。 + +{{% /capture %}} + + +{{% capture body %}} + + +## 组织资源配置 + +许多应用需要创建多个资源,例如 Deployment 和 Service。可以通过将多个资源组合在同一个文件中(在 YAML 中以 `---` 分隔)来简化对它们的管理。例如: + +{{< codenew file="application/nginx-app.yaml" >}} + + +可以用创建单个资源相同的方式来创建多个资源: + +```shell +$ kubectl create -f https://k8s.io/examples/application/nginx-app.yaml +service/my-nginx-svc created +deployment.apps/my-nginx created +``` + + +资源将按照它们在文件中的顺序创建。因此,最好先指定服务,这样在控制器(例如 Deployment)创建 Pod 时能够确保调度器可以将与服务关联的多个 Pod 分散到不同节点。 + + +`kubectl create` 也接受多个 `-f` 参数: + +```shell +$ kubectl create -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml +``` + + +还可以指定目录路径,而不用添加多个单独的文件: + +```shell +$ kubectl create -f https://k8s.io/examples/application/nginx/ +``` + + +`kubectl` 将读取任何后缀为 `.yaml`,`.yml` 或者 `.json` 的文件。 + +建议的做法是,将同一个微服务或同一应用层相关的资源放到同一个文件中,将同一个应用相关的所有文件按组存放到同一个目录中。如果应用的各层使用 DNS 相互绑定,那么您可以简单地将堆栈的所有组件一起部署。 + +还可以使用 URL 作为配置源,便于直接使用已经提交到 Github 上的配置文件进行部署: + +```shell +$ kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml +deployment.apps/my-nginx created +``` + + +## kubectl 中的批量操作 + +资源创建并不是 `kubectl` 可以批量执行的唯一操作。`kubectl` 还可以从配置文件中提取资源名,以便执行其他操作,特别是删除您之前创建的资源: + +```shell +$ kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml +deployment.apps "my-nginx" deleted +service "my-nginx-svc" deleted +``` + + +在仅有两种资源的情况下,可以使用"资源类型/资源名"的语法在命令行中同时指定这两个资源: + +```shell +$ kubectl delete deployments/my-nginx services/my-nginx-svc +``` + + +对于资源数目较大的情况,您会发现使用 `-l` 或 `--selector` 指定的筛选器(标签查询)能很容易根据标签筛选资源: + +```shell +$ kubectl delete deployment,services -l app=nginx +deployment.apps "my-nginx" deleted +service "my-nginx-svc" deleted +``` + + +由于 `kubectl` 用来输出资源名称的语法与其所接受的资源名称语法相同,所以很容易使用 `$()` 或 `xargs` 进行链式操作: + +```shell +$ kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service) +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +my-nginx-svc LoadBalancer 10.0.0.208 80/TCP 0s +``` + + +上面的命令中,我们首先使用 `examples/application/nginx/` 下的配置文件创建资源,并使用 `-o name` 的输出格式(以"资源/名称"的形式打印每个资源)打印所创建的资源。然后,我们通过 `grep` 来过滤 "service",最后再打印 `kubectl get` 的内容。 + + +如果您碰巧在某个路径下的多个子路径中组织资源,那么也可以递归地在所有子路径上执行操作,方法是在 `--filename,-f` 后面指定 `--recursive` 或者 `-R`。 + + +例如,假设有一个目录路径为 `project/k8s/development`,它保存开发环境所需的所有清单,并按资源类型组织: + +``` +project/k8s/development +├── configmap +│   └── my-configmap.yaml +├── deployment +│   └── my-deployment.yaml +└── pvc + └── my-pvc.yaml +``` + + +默认情况下,对 `project/k8s/development` 执行的批量操作将停止在目录的第一级,而不是处理所有子目录。 +如果我们试图使用以下命令在此目录中创建资源,则会遇到一个错误: + +```shell +$ kubectl create -f project/k8s/development +error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin) +``` + + +然而,在 `--filename,-f` 后面标明 `--recursive` 或者 `-R` 之后: + +```shell +$ kubectl create -f project/k8s/development --recursive +configmap/my-config created +deployment.apps/my-deployment created +persistentvolumeclaim/my-pvc created +``` + + +`--recursive` 可以用于接受 `--filename,-f` 参数的任何操作,例如:`kubectl {create,get,delete,describe,rollout}` 等。 + +有多个 `-f` 参数出现的时候,`--recursive` 参数也能正常工作: + +```shell +$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive +namespace/development created +namespace/staging created +configmap/my-config created +deployment.apps/my-deployment created +persistentvolumeclaim/my-pvc created +``` + + +如果您有兴趣学习更多关于 `kubectl` 的内容,请阅读 [kubectl 概述](/docs/reference/kubectl/overview/)。 + + +## 有效地使用标签 + +到目前为止我们使用的示例中的资源最多使用了一个标签。在许多情况下,应使用多个标签来区分集合。 + + +例如,不同的应用可能会为 `app` 标签设置不同的值。 +但是,类似 [guestbook 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/guestbook/) 这样的多层应用,还需要区分每一层。前端可以带以下标签: + +```yaml + labels: + app: guestbook + tier: frontend +``` + + +Redis 的主节点和从节点会有不同的 `tier` 标签,甚至还有一个额外的 `role` 标签: + +```yaml + labels: + app: guestbook + tier: backend + role: master +``` + + +以及 + +```yaml + labels: + app: guestbook + tier: backend + role: slave +``` + + +标签允许我们按照标签指定的任何维度对我们的资源进行切片和切块: + +```shell +$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml +$ kubectl get pods -Lapp -Ltier -Lrole +NAME READY STATUS RESTARTS AGE APP TIER ROLE +guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend +guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend +guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend +guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master +guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave +guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave +my-nginx-divi2 1/1 Running 0 29m nginx +my-nginx-o0ef1 1/1 Running 0 29m nginx +$ kubectl get pods -lapp=guestbook,role=slave +NAME READY STATUS RESTARTS AGE +guestbook-redis-slave-2q2yf 1/1 Running 0 3m +guestbook-redis-slave-qgazl 1/1 Running 0 3m +``` + + +## 金丝雀部署 + + +另一个需要多标签的场景是用来区分同一组件的不同版本或者不同配置的多个部署。常见的做法是部署一个使用*金丝雀发布*来部署新应用版本(在 pod 模板中通过镜像标签指定),保持新旧版本应用同时运行,这样,新版本在完全发布之前也可以接收实时的生产流量。 + + +例如,您可以使用 `track` 标签来区分不同的版本。 + +主要稳定的发行版将有一个 `track` 标签,其值为 `stable`: + +```yaml + name: frontend + replicas: 3 + ... + labels: + app: guestbook + tier: frontend + track: stable + ... + image: gb-frontend:v3 +``` + + +然后,您可以创建 guestbook 前端的新版本,让这些版本的 `track` 标签带有不同的值(即 `canary`),以便两组 pod 不会重叠: + +```yaml + name: frontend-canary + replicas: 1 + ... + labels: + app: guestbook + tier: frontend + track: canary + ... + image: gb-frontend:v4 +``` + + +前端服务通过选择标签的公共子集(即忽略 `track` 标签)来覆盖两组副本,以便流量可以转发到两个应用: + +```yaml + selector: + app: guestbook + tier: frontend +``` + + +您可以调整 `stable` 和 `canary` 版本的副本数量,以确定每个版本将接收实时生产流量的比例(在本例中为 3:1)。一旦有信心,您就可以将新版本应用的 `track` 标签的值从 `canary` 替换为 `stable`,并且将老版本应用删除。 + + +想要了解更具体的示例,请查看 [Ghost 部署教程](https://github.com/kelseyhightower/talks/tree/master/kubecon-eu-2016/demo#deploy-a-canary)。 + + +## 更新标签 + +有时,现有的 pod 和其它资源需要在创建新资源之前重新标记。这可以用 `kubectl label` 完成。 +例如,如果想要将所有 nginx pod 标记为前端层,只需运行: + +```shell +$ kubectl label pods -l app=nginx tier=fe +pod/my-nginx-2035384211-j5fhi labeled +pod/my-nginx-2035384211-u2c7e labeled +pod/my-nginx-2035384211-u3t6x labeled +``` + + +首先用标签 "app=nginx" 过滤所有的 pod,然后用 "tier=fe" 标记它们。想要查看您刚才标记的 pod,请运行: + +```shell +$ kubectl get pods -l app=nginx -L tier +NAME READY STATUS RESTARTS AGE TIER +my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe +my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe +my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe +``` + + +这将输出所有 "app=nginx" 的 pod,并有一个额外的描述 pod 的 tier 的标签列(用参数 `-L` 或者 `--label-columns` 标明)。 + +想要了解更多信息,请参考 [标签](/docs/concepts/overview/working-with-objects/labels/) 和 [kubectl label](/docs/reference/generated/kubectl/kubectl-commands/#label)。 + + +## 更新注解 + +有时,您可能希望将注解附加到资源中。注解是 API 客户端(如工具、库等)用于检索的任意非标识元数据。这可以通过 `kubectl annotate` 来完成。例如: + +```shell +$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx' +$ kubectl get pods my-nginx-v4-9gw19 -o yaml +apiversion: v1 +kind: pod +metadata: + annotations: + description: my frontend running nginx +... +``` + + +想要了解更多信息,请参考 [注解](/docs/concepts/overview/working-with-objects/annotations/) 和 [kubectl annotate](/docs/reference/generated/kubectl/kubectl-commands/#annotate) 文档。 + + +## 缩扩您的应用 + +当应用上的负载增长或收缩时,使用 `kubectl` 能够轻松实现规模的缩扩。例如,要将 nginx 副本的数量从 3 减少到 1,请执行以下操作: + +```shell +$ kubectl scale deployment/my-nginx --replicas=1 +deployment.extensions/my-nginx scaled +``` + + +现在,您的 deployment 管理的 pod 只有一个了。 + +```shell +$ kubectl get pods -l app=nginx +NAME READY STATUS RESTARTS AGE +my-nginx-2035384211-j5fhi 1/1 Running 0 30m +``` + + +想要让系统自动选择需要 nginx 副本的数量,范围从 1 到 3,请执行以下操作: + +```shell +$ kubectl autoscale deployment/my-nginx --min=1 --max=3 +horizontalpodautoscaler.autoscaling/my-nginx autoscaled +``` + + +现在,您的 nginx 副本将根据需要自动地增加或者减少。 + +想要了解更多信息,请参考 [kubectl scale](/docs/reference/generated/kubectl/kubectl-commands/#scale), [kubectl autoscale](/docs/reference/generated/kubectl/kubectl-commands/#autoscale) 和 [pod 水平自动伸缩](/docs/tasks/run-application/horizontal-pod-autoscale/) 文档。 + + +## 就地更新资源 + +有时,有必要对您所创建的资源进行小范围、无干扰地更新。 + +### kubectl apply + + +建议在源代码管理中维护一组配置文件(参见[配置即代码](http://martinfowler.com/bliki/InfrastructureAsCode.html)),这样,它们就可以和应用代码一样进行维护和版本管理。然后,您可以用 [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands/#apply) 将配置变更应用到集群中。 + + +这个命令将会把推送的版本与以前的版本进行比较,并应用您所做的更改,但是不会自动覆盖任何你没有指定更改的属性。 + +```shell +$ kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml +deployment.apps/my-nginx configured +``` + + +注意,`kubectl apply` 将为资源增加一个额外的注解,以确定自上次调用以来对配置的更改。当调用它时,`kubectl apply` 会在以前的配置、提供的输入和资源的当前配置之间找出三方差异,以确定如何修改资源。 + + +目前,新创建的资源是没有这个注解的,所以,第一次调用 `kubectl apply` 将使用提供的输入和资源的当前配置双方之间差异进行比较。在第一次调用期间,它无法检测资源创建时属性集的删除情况。因此,不会删除它们。 + + +所有后续调用 `kubectl apply` 以及其它修改配置的命令,如 `kubectl replace` 和 `kubectl edit`,都将更新注解,并允许随后调用的 `kubectl apply` 使用三方差异进行检查和执行删除。 + + +{{< note >}} +想要使用 apply,请始终使用 `kubectl apply` 或 `kubectl create --save-config` 创建资源。 +{{< /note >}} + +### kubectl edit + + +或者,您也可以使用 `kubectl edit` 更新资源: + +```shell +$ kubectl edit deployment/my-nginx +``` + + +这相当于首先 `get` 资源,在文本编辑器中编辑它,然后用更新的版本 `apply` 资源: + +```shell +$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml +$ vi /tmp/nginx.yaml +# do some edit, and then save the file +$ kubectl apply -f /tmp/nginx.yaml +deployment.apps/my-nginx configured +$ rm /tmp/nginx.yaml +``` + + +这使您可以更加容易地进行更重大的更改。请注意,可以使用 `EDITOR` 或 `KUBE_EDITOR` 环境变量来指定编辑器。 + +想要了解更多信息,请参考 [kubectl edit](/docs/reference/generated/kubectl/kubectl-commands/#edit) 文档。 + +### kubectl patch + + +您可以使用 `kubectl patch` 来更新 API 对象。此命令支持 JSON patch,JSON merge patch,以及 strategic merge patch。 请参考 +[使用 kubectl patch 更新 API 对象](/docs/tasks/run-application/update-api-object-kubectl-patch/) +和 +[kubectl patch](/docs/reference/generated/kubectl/kubectl-commands/#patch). + + +## 破坏性的更新 + +在某些情况下,您可能需要更新某些初始化后无法更新的资源字段,或者您可能只想立即进行递归更改,例如修复 Deployment 创建的不正常的 Pod。若要更改这些字段,请使用 `replace --force`,它将删除并重新创建资源。在这种情况下,您可以简单地修改原始配置文件: + +```shell +$ kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force +deployment.apps/my-nginx deleted +deployment.apps/my-nginx replaced +``` + + +## 在不中断服务的情况下更新应用 + + +在某些时候,您最终需要更新已部署的应用,通常都是通过指定新的镜像或镜像标签,如上面的金丝雀发布的场景中所示。`kubectl` 支持几种更新操作,每种更新操作都适用于不同的场景。 + + +我们将指导您通过 Deployment 如何创建和更新应用。如果部署的应用由 `ReplicationController` 管理,那么您应该阅读 [怎么样使用 `kubectl rolling-update`](/docs/tasks/run-application/rolling-update-replication-controller/)。 + + +假设您正运行的是 1.7.9 版本的 nginx: + +```shell +$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3 +deployment.apps/my-nginx created +``` + + +要更新到 1.9.1 版本,只需使用我们前面学到的 kubectl 命令将 `.spec.template.spec.containers[0].image` 从 `nginx:1.7.9` 修改为 `nginx:1.9.1`。 + +```shell +$ kubectl edit deployment/my-nginx +``` + + +没错,就是这样!Deployment 将在后台逐步更新已经部署的 nginx 应用。它确保在更新过程中,只有一定数量的旧副本被开闭,并且只有一定基于所需 pod 数量的新副本被创建。想要了解更多细节,请参考 [Deployment](/docs/concepts/workloads/controllers/deployment/)。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +- [学习怎么样使用 `kubectl` 观察和调试应用](/docs/tasks/debug-application-cluster/debug-application-introspection/) +- [配置最佳实践和技巧](/docs/concepts/configuration/overview/) + +{{% /capture %}} diff --git a/content/zh/docs/concepts/configuration/_index.md b/content/zh/docs/concepts/configuration/_index.md new file mode 100644 index 0000000000000..5bf9c6c13813d --- /dev/null +++ b/content/zh/docs/concepts/configuration/_index.md @@ -0,0 +1,11 @@ +--- +title: "配置" +weight: 70 +--- + + \ No newline at end of file diff --git a/content/zh/docs/concepts/configuration/manage-compute-resources-container.md b/content/zh/docs/concepts/configuration/manage-compute-resources-container.md index 0d798d058bf10..e1a93014874a2 100644 --- a/content/zh/docs/concepts/configuration/manage-compute-resources-container.md +++ b/content/zh/docs/concepts/configuration/manage-compute-resources-container.md @@ -1,22 +1,74 @@ --- +title: 为容器管理计算资源 +content_template: templates/concept +weight: 20 +feature: + title: 自动装箱 + description: > + 根据资源需求和其他约束自动放置容器,同时不会牺牲可用性,将任务关键工作负载和尽力服务工作负载进行混合放置,以提高资源利用率并节省更多资源。 +--- + + {{% capture overview %}} -当您定义 [Pod](/docs/user-guide/pods) 的时候可以选择为每个容器指定需要的 CPU 和内存(RAM)大小。当为容器指定了资源请求后,调度器就能够更好的判断出将容器调度到哪个节点上。如果您还为容器指定了资源限制,节点上的资源就可以按照指定的方式做竞争。关于资源请求和限制的不同点和更多资料请参考 [Resource QoS](https://git.k8s.io/community/contributors/design-proposals/resource-qos.md)。 + +当您定义 [Pod](/docs/user-guide/pods) 的时候可以选择为每个容器指定需要的 CPU 和内存(RAM)大小。当为容器指定了资源请求后,调度器就能够更好的判断出将容器调度到哪个节点上。如果您还为容器指定了资源限制,Kubernetes 就可以按照指定的方式来处理节点上的资源竞争。关于资源请求和限制的不同点和更多资料请参考 [Resource QoS](https://git.k8s.io/community/contributors/design-proposals/resource-qos.md)。 {{% /capture %}} {{% capture body %}} + + ## 资源类型 -*CPU* 和 *内存* 都是 *资源类型* 。资源类型具有基本单位。CPU 的单位是 core,内存的单位是 byte。 +*CPU* 和*内存*都是*资源类型*。资源类型具有基本单位。CPU 的单位是核心数,内存的单位是字节。 + +CPU和内存统称为*计算资源*,也可以称为*资源*。计算资源的数量是可以被请求、分配、消耗和可测量的。它们与 [API 资源](/docs/concepts/overview/kubernetes-api/) 不同。 API 资源(如 Pod 和 [Service](/docs/concepts/services-networking/service/))是可通过 Kubernetes API server 读取和修改的对象。 -CPU和内存统称为*计算资源* ,也可以称为*资源* 。计算资源的数量是可以被请求、分配、消耗和可测量的。它们与 [API 资源](/docs/api/) 不同。 API 资源(如 Pod 和 [Service](/docs/user-guide/services))是可通过 Kubernetes API server 读取和修改的对象。 + ## Pod 和 容器的资源请求和限制 @@ -29,6 +81,27 @@ Pod 中的每个容器都可以指定以下的一个或者多个值: 尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。 + + ## CPU 的含义 CPU 资源的限制和请求以 *cpu* 为单位。 @@ -44,6 +117,14 @@ Kubernetes 中的一个 cpu 等于: CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。 + + ## 内存的含义 内存的限制和请求以字节为单位。您可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。您还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。例如,以下代表大致相同的值: @@ -52,6 +133,14 @@ CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单 128974848, 129e6, 129M, 123Mi ``` + + 下面是个例子。 以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。 @@ -83,27 +172,91 @@ spec: cpu: "500m" ``` + + ## 具有资源请求的 Pod 如何调度 当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。当资源使用量稍后增加时,例如在请求率的每日峰值期间,这可以防止节点上的资源短缺。 + + ## 具有资源限制的 Pod 如何运行 当 kubelet 启动一个 Pod 的容器时,它会将 CPU 和内存限制传递到容器运行时。 当使用 Docker 时: -- `spec.containers[].resources.requests.cpu` 的值将转换成 millicore 值,这是个浮点数,并乘以1024,这个数字中的较大者或2用作 `docker run` 命令中的[ `--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) 标志的值。 + + +- `spec.containers[].resources.requests.cpu` 的值将转换成 millicore 值,这是个浮点数,并乘以 1024,这个数字中的较大者或 2 用作 `docker run` 命令中的[ `--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) 标志的值。 + - `spec.containers[].resources.limits.cpu` 被转换成 millicore 值。被乘以 100000 然后 除以 1000。这个数字用作 `docker run` 命令中的 [`--cpu-quota`](https://docs.docker.com/engine/reference/run/#/cpu-quota-constraint) 标志的值。[`--cpu-quota` ] 标志被设置成了 100000,表示测量配额使用的默认100ms 周期。如果 [`--cpu-cfs-quota`] 标志设置为 true,则 kubelet 会强制执行 cpu 限制。从 Kubernetes 1.2 版本起,此标志默认为 true。 + + + + {{< note >}} + 默认配额限制为 100 毫秒。 CPU配额的最小单位为 1 毫秒。 + {{}} + - `spec.containers[].resources.limits.memory` 被转换为整型,作为 `docker run` 命令中的 [`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) 标志的值。 + + 如果容器超过其内存限制,则可能会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。 如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。 容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。 -要确定容器是否由于资源限制而无法安排或被杀死,请参阅 [疑难解答](#troubleshooting) 部分。 +要确定容器是否由于资源限制而无法安排或被杀死,请参阅[疑难解答](#troubleshooting) 部分。 + + ## 监控计算资源使用 @@ -111,6 +264,14 @@ Pod 的资源使用情况被报告为 Pod 状态的一部分。 如果为集群配置了 [可选监控](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/cluster-monitoring/README.md),则可以从监控系统检索 Pod 资源的使用情况。 + + ## 疑难解答 ### 我的 Pod 处于 pending 状态且事件信息显示 failedScheduling @@ -124,8 +285,29 @@ Events: 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others ``` + + 在上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,您可以尝试如下几件事情: +- 向集群添加更多节点。 +- 终止不需要的 Pod,为待处理的 Pod 腾出空间。 +- 检查 Pod 所需的资源是否大于所有节点的资源。 例如,如果全部节点的容量为`cpu:1`,那么一个请求为 `cpu:1.1`的 Pod 永远不会被调度。 + +您可以使用 `kubectl describe nodes` 命令检查节点容量和分配的数量。 例如: + + ```shell $ kubectl describe nodes e2e-test-minion-group-4lw4 Name: e2e-test-minion-group-4lw4 @@ -156,6 +338,21 @@ Allocated resources: 680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%) ``` + + 在上面的输出中,您可以看到如果 Pod 请求超过 1120m CPU 或者 6.23Gi 内存,节点将无法满足。 通过查看 `Pods` 部分,您将看到哪些 Pod 占用的节点上的资源。 @@ -164,6 +361,13 @@ Pod 可用的资源量小于节点容量,因为系统守护程序使用一部 可以将 [资源配额](/docs/concepts/policy/resource-quotas/) 功能配置为限制可以使用的资源总量。如果与 namespace 配合一起使用,就可以防止一个团队占用所有资源。 + + ## 我的容器被终止了 您的容器可能因为资源枯竭而被终止了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用 `kubectl describe pod`: @@ -210,6 +414,13 @@ Events: 您可以使用 `kubectl get pod` 命令加上 `-o go-template=...` 选项来获取之前终止容器的状态。 + + ```shell [13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc Container Name: simmemleak @@ -218,6 +429,10 @@ LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-0 您可以看到容器因为 `reason:OOM killed` 被终止,`OOM` 表示 Out Of Memory。 + + ## 不透明整型资源(Alpha功能) Kubernetes 1.5 版本中引入不透明整型资源。不透明的整数资源允许集群运维人员发布新的节点级资源,否则系统将不了解这些资源。 @@ -275,6 +490,26 @@ spec: pod.alpha.kubernetes.io/opaque-int-resource-foo: 1 ``` + + ## 计划改进 在 kubernetes 1.5 版本中仅允许在容器上指定资源量。计划改进对所有容器在 Pod 中共享资源的计量,如 [emptyDir volume](/docs/concepts/storage/volumes/#emptydir)。 @@ -288,6 +523,12 @@ Kubernetes 通过支持通过多级别的 [服务质量](http://issue.k8s.io/168 {{% /capture %}} {{% capture whatsnext %}} + - 获取将 [CPU 和内存资源分配给容器](/docs/tasks/configure-pod-container/assign-cpu-ram-container/) 的实践经验 - [容器](/docs/api-reference/{{< param "version" >}}/#container-v1-core) diff --git a/content/zh/docs/concepts/configuration/organize-cluster-access-kubeconfig.md b/content/zh/docs/concepts/configuration/organize-cluster-access-kubeconfig.md new file mode 100644 index 0000000000000..ac311a8e46955 --- /dev/null +++ b/content/zh/docs/concepts/configuration/organize-cluster-access-kubeconfig.md @@ -0,0 +1,280 @@ +--- +title: 使用 kubeconfig 文件组织集群访问 +content_template: templates/concept +weight: 60 +--- + + +{{% capture overview %}} + + +使用 kubeconfig 文件来组织有关集群、用户、命名空间和身份认证机制的信息。`kubectl` 命令行工具使用 kubeconfig 文件来查找选择集群所需的信息,并与集群的 API 服务器进行通信。 + + +{{< note >}} +注意:用于配置集群访问的文件称为 *kubeconfig 文件*。这是引用配置文件的通用方法。这并不意味着有一个名为 `kubeconfig` 的文件 +{{< /note >}} + + +默认情况下,`kubectl` 在 `$HOME/.kube` 目录下查找名为 `config` 的文件。您可以通过设置 `KUBECONFIG` 环境变量或者设置[`--kubeconfig`](/docs/reference/generated/kubectl/kubectl/)参数来指定其他 kubeconfig 文件。 + + +有关创建和指定 kubeconfig 文件的分步说明,请参阅[配置对多集群的访问](/docs/tasks/access-application-cluster/configure-access-multiple-clusters)。 + +{{% /capture %}} + + +{{% capture body %}} + + +## 支持多集群、用户和身份认证机制 + + +假设您有多个集群,并且您的用户和组件以多种方式进行身份认证。比如: + + +- 正在运行的 kubelet 可能使用证书在进行认证。 +- 用户可能通过令牌进行认证。 +- 管理员可能拥有多个证书集合提供给各用户。 + + +使用 kubeconfig 文件,您可以组织集群、用户和命名空间。您还可以定义上下文,以便在集群和命名空间之间快速轻松地切换。 + + +## 上下文(Context) + + +通过 kubeconfig 文件中的 *context* 元素,使用简便的名称来对访问参数进行分组。每个上下文都有三个参数:cluster、namespace 和 user。默认情况下,`kubectl` 命令行工具使用 *当前上下文* 中的参数与集群进行通信。 + + +选择当前上下文 +``` +kubectl config use-context +``` + + +## KUBECONFIG 环境变量 + + +`KUBECONFIG` 环境变量包含一个 kubeconfig 文件列表。对于 Linux 和 Mac,列表以冒号分隔。对于 Windows,列表以分号分隔。`KUBECONFIG` 环境变量不是必要的。如果 `KUBECONFIG` 环境变量不存在,`kubectl` 使用默认的 kubeconfig 文件,`$HOME/.kube/config`。 + + +如果 `KUBECONFIG` 环境变量存在,`kubectl` 使用 `KUBECONFIG` 环境变量中列举的文件合并后的有效配置。 + + +## 合并 kubeconfig 文件 + + +要查看配置,输入以下命令: +```shell +kubectl config view +``` + + +如前所述,输出可能来自 kubeconfig 文件,也可能是合并多个 kubeconfig 文件的结果。 + + +以下是 `kubectl` 在合并 kubeconfig 文件时使用的规则。 + + +1. 如果设置了 `--kubeconfig` 参数,则仅使用指定的文件。不进行合并。此参数只能使用一次。 + + 否则,如果设置了 `KUBECONFIG` 环境变量,将它用作应合并的文件列表。根据以下规则合并 `KUBECONFIG` 环境变量中列出的文件: + + * 忽略空文件名。 + * 对于内容无法反序列化的文件,产生错误信息。 + * 第一个设置特定值或者映射键的文件将生效。 + * 永远不会更改值或者映射键。示例:保留第一个文件的上下文以设置 `current-context`。示例:如果两个文件都指定了 `red-user`,则仅使用第一个文件的 `red-user` 中的值。即使第二个文件在 `red-user` 下有非冲突条目,也要丢弃它们。 + + + 有关设置 `KUBECONFIG` 环境变量的示例,请参阅[设置 KUBECONFIG 环境变量](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#set-the-kubeconfig-environment-variable)。 + + + 否则,使用默认的 kubeconfig 文件, `$HOME/.kube/config`,不进行合并。 + + +1. 根据此链中的第一个匹配确定要使用的上下文。 + + 1. 如果存在,使用 `--context` 命令行参数。 + 2. 使用合并的 kubeconfig 文件中的 `current-context`。 + + + 这种场景下允许空上下文。 + + +1. 确定集群和用户。此时,可能有也可能没有上下文。根据此链中的第一个匹配确定集群和用户,这将运行两次:一次用于用户,一次用于集群。 + + 1. 如果存在,使用命令行参数:`--user` 或者 `--cluster`。 + 2. 如果上下文非空,从上下文中获取用户或集群。 + + + 这种场景下用户和集群可以为空。 + + +1. 确定要使用的实际集群信息。此时,可能有也可能没有集群信息。基于此链构建每个集群信息;第一个匹配项会被采用: + + 1. 如果存在:`--server`、`--certificate-authority` 和 `--insecure-skip-tls-verify`,使用命令行参数。 + 2. 如果合并的 kubeconfig 文件中存在集群信息属性,则使用它们。 + 3. 如果没有 server 配置,则配置无效。 + + +2. 确定要使用的实际用户信息。使用与集群信息相同的规则构建用户信息,但每个用户只允许一种身份认证技术: + + 1. 如果存在:`--client-certificate`、`--client-key`、`--username`、`--password` 和 `--token`,使用命令行参数。 + 2. 使用合并的 kubeconfig 文件中的 `user` 字段。 + 3. 如果存在两种冲突技术,则配置无效。 + + +3. 对于仍然缺失的任何信息,使用其对应的默认值,并可能提示输入身份认证信息。 + + +## 文件引用 + + +kubeconfig 文件中的文件和路径引用是相对于 kubeconfig 文件的位置。命令行上的文件引用是相当对于当前工作目录的。在 `$HOME/.kube/config` 中,相对路径按相对路径存储,绝对路径按绝对路径存储。 + +{{% /capture %}} + + +{{% capture whatsnext %}} + + +* [配置对多集群的访问](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) +* [`kubectl config`](/docs/reference/generated/kubectl/kubectl-commands#config) +{{% /capture %}} + + diff --git a/content/zh/docs/concepts/configuration/overview.md b/content/zh/docs/concepts/configuration/overview.md new file mode 100644 index 0000000000000..98e04965d0f96 --- /dev/null +++ b/content/zh/docs/concepts/configuration/overview.md @@ -0,0 +1,268 @@ +--- +reviewers: +- mikedanese +title: 配置最佳实践 +content_template: templates/concept +weight: 10 +--- + + +{{% capture overview %}} + +本文档重点介绍并整合了整个用户指南、入门文档和示例中介绍的配置最佳实践。 + + +这是一份活文件。 +如果您认为某些内容不在此列表中但可能对其他人有用,请不要犹豫,提交问题或提交 PR。 +{{% /capture %}} + +{{% capture body %}} + +## 一般配置提示 + + +- 定义配置时,请指定最新的稳定 API 版本。 + + +- 在推送到集群之前,配置文件应存储在版本控制中。 + 这允许您在必要时快速回滚配置更改。 + 它还有助于集群重新创建和恢复。 + + +- 使用 YAML 而不是 JSON 编写配置文件。虽然这些格式几乎可以在所有场景中互换使用,但 YAML 往往更加用户友好。 + + +- 只要有意义,就将相关对象分组到一个文件中。 + 一个文件通常比几个文件更容易管理。 + 请参阅[guestbook-all-in-one.yaml](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/guestbook/all-in-one/guestbook-all-in-one.yaml) 文件作为此语法的示例。 + + +- 另请注意,可以在目录上调用许多`kubectl`命令。 + 例如,你可以在配置文件的目录中调用`kubectl apply`。 + + +- 不要不必要地指定默认值:简单的最小配置会降低错误的可能性。 + + +- 将对象描述放在注释中,以便更好地进行内省。 + + + +## “Naked”Pods 与 ReplicaSet,Deployment 和 Jobs + + +- 如果您能避免,不要使用 naked Pods(即,Pod 未绑定到[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 或[Deployment](/docs/concepts/workloads/controllers/deployment/))。 + 如果节点发生故障,将不会重新安排 Naked Pods。 + + + 部署,它创建一个 ReplicaSet 以确保所需数量的 Pod 始终可用,并指定替换 Pod 的策略(例如 [RollingUpdate](/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment)),除了一些显式的[`restartPolicy: Never`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy)场景之外,几乎总是优先考虑直接创建 Pod。 +[Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/) 也可能是合适的。 + + + +## 服务 + + +- 在其相应的后端工作负载(Deployment 或 ReplicaSet)之前,以及在需要访问它的任何工作负载之前创建[服务](/docs/concepts/services-networking/service/)。 + 当 Kubernetes 启动容器时,它提供指向启动容器时正在运行的所有服务的环境变量。 + 例如,如果存在名为`foo`当服务,则所有容器将在其初始环境中获取以下变量。 + + ```shell + FOO_SERVICE_HOST= + FOO_SERVICE_PORT= + ``` + + + *这确实意味着订购要求* - 必须在`Pod`本身之前创建`Pod`想要访问的任何`Service`,否则将不会填充环境变量。 + DNS没有此限制。 + + +- 一个可选(尽管强烈推荐)[cluster add-on](/docs/concepts/cluster-administration/addons/)是 DNS 服务器。DNS 服务器为新的`Services`监视 Kubernetes API,并为每个创建一组 DNS 记录。 + 如果在整个集群中启用了 DNS,则所有`Pods`应该能够自动对`Services`进行名称解析。 + + +- 除非绝对必要,否则不要为 Pod 指定`hostPort`。 + 将 Pod 绑定到`hostPort`时,它会限制 Pod 可以调度的位置数,因为每个<`hostIP`, `hostPort`, `protocol`>组合必须是唯一的。如果您没有明确指定`hostIP`和`protocol`,Kubernetes将使用`0.0.0.0`作为默认`hostIP`和`TCP`作为默认`protocol`。 + + + 如果您只需要访问端口以进行调试,则可以使用[apiserver proxy](/docs/tasks/access-application-cluster/access-cluster/#manually-constructing-apiserver-proxy-urls)或[`kubectl port-forward`](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)。 + + + 如果您明确需要在节点上公开 Pod 的端口,请在使用`hostPort`之前考虑使用[NodePort](/docs/concepts/services-networking/service/#nodeport) 服务。 + + +- 避免使用`hostNetwork`,原因与`hostPort`相同。 + + +- 当您不需要`kube-proxy`负载平衡时,使用 [无头服务](/docs/concepts/services-networking/service/#headless- +services) (具有`None`的`ClusterIP`)以便于服务发现。 + + +## 使用标签 + + +- 定义并使用[标签](/docs/concepts/overview/working-with-objects/labels/)来识别应用程序或部署的__semantic attributes__,例如`{ app: myapp, tier: frontend, phase: test, deployment: v3 }`。 + 您可以使用这些标签为其他资源选择合适的 Pod;例如,一个选择所有`tier: frontend` Pod 的服务,或者`app: myapp`的所有`phase: test`组件。 + 有关此方法的示例,请参阅[留言板](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/guestbook/) 。 + + +通过从选择器中省略特定发行版的标签,可以使服务跨越多个部署。 +[部署](/docs/concepts/workloads/controllers/deployment/)可以在不停机的情况下轻松更新正在运行的服务。 + + +部署描述了对象的期望状态,并且如果对该规范的更改是_applied_,则部署控制器以受控速率将实际状态改变为期望状态。 + + +- 您可以操纵标签进行调试。 +- 由于 Kubernetes 控制器(例如 ReplicaSet)和服务使用选择器标签与 Pod 匹配,因此从 Pod 中删除相关标签将阻止其被控制器考虑或由服务提供服务流量。 + 如果删除现有 Pod 的标签,其控制器将创建一个新的 Pod 来取代它。 + 这是在"隔离"环境中调试先前"实时"Pod 的有用方法。 + 要以交互方式删除或添加标签,请使用[`kubectl label`](/docs/reference/generated/kubectl/kubectl-commands#label)。 + + +## 容器镜像 + + +当 [kubelet](/docs/admin/kubelet/)尝试拉取指定的镜像时,[imagePullPolicy](/ docs / concepts / containers / images / #updating-images)和镜像的标签会生效。 + + +- `imagePullPolicy: IfNotPresent`:仅当镜像在本地不存在时镜像才被拉取。 + + +- `imagePullPolicy: Always`:每次启动 pod 的时候都会拉取镜像。 + + +- 省略`imagePullPolicy`,镜像标签为`:latest`或被省略,`Always`被应用。 + + +- `imagePullPolicy`被省略,并且镜像的标签被指定且不是`:latest`,`IfNotPresent`被应用。 + + +- `imagePullPolicy: Never`:镜像被假设存在于本地。 + 没有尝试拉取镜像。 + + +{{< note >}} +要确保容器始终使用相同版本的镜像,你可以指定其 [摘要](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier), 例如`sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`。 +摘要唯一地标识出镜像的指定版本,因此除非您更改摘要值,否则 Kubernetes 永远不会更新它。 +{{< /note >}} + + +{{< note >}} +在生产中部署容器时应避免使用 `:latest` 标记,因为更难跟踪正在运行的镜像版本,并且更难以正确回滚。 +{{< /note >}} + + +{{< note >}} +底层镜像提供程序的缓存语义甚至使 `imagePullPolicy: Always`变得高效。 +例如,对于 Docker,如果镜像已经存在,则拉取尝试很快,因为镜像层都被缓存并且不需要镜像下载。 +{{< /note >}} + + +## 使用 kubectl + + +- 使用`kubectl apply -f `。 + 它在``中的所有`.yaml`,`.yml`和`.json`文件中查找 Kubernetes 配置,并将其传递给`apply`。 + + +- 使用标签选择器进行`get`和`delete`操作,而不是特定的对象名称。 +- 请参阅[标签选择器](/docs/concepts/overview/working-with-objects/labels/#label-selectors)和[有效使用标签]部分(/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively)。 + + +- 使用`kubectl run`和`kubectl expose`来快速创建单容器部署和服务。 + 有关示例,请参阅[使用服务访问集群中的应用程序](/docs/tasks/access-application-cluster/service-access-application-cluster/)。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/configuration/scheduler-perf-tuning.md b/content/zh/docs/concepts/configuration/scheduler-perf-tuning.md new file mode 100644 index 0000000000000..3ca2c81c8d46e --- /dev/null +++ b/content/zh/docs/concepts/configuration/scheduler-perf-tuning.md @@ -0,0 +1,175 @@ +--- +reviewers: +- bsalamat +title: 调度器性能调优 +content_template: templates/concept +weight: 70 +--- + + + +{{% capture overview %}} + +{{< feature-state for_k8s_version="1.12" >}} + + + +Kube-scheduler 是 Kubernetes 的默认调度器。负责将 Pods 安排到集群中的节点上。 +集群中达到 Pod 调度要求的节点也被称为这个 Pod 的“可行性”节点。 +调度器首先找出 Pod 的可行性节点,然后运行一套打分函数来为可行性节点打分, +最后挑选出分数最高的可行性节点来运行 Pod。随后,调度器将这个决定通知给 API 服务器, +这个通知流程叫做“绑定”("Binding")。 + +{{% /capture %}} + +{{% capture body %}} + + +## 可行性打分的节点比例 + + + +在 Kubernetes 1.12 之前, Kube-scheduler 曾经是检查集群中所有节点的可行性,并为它们依次打分。 +而在 Kubernetes 1.12 中加入了一项新的功能,允许调度器在找到足够合适的可行性节点之后,停止搜索。 +这项功能将提高调度器在大型集群应用中的性能。这是一个比例参数,通过一个名为 `percentageOfNodesToScore` 的配置选项, +指明了集群大小中的比例。参数值范围在 1 到 100 之间。其它的数值将被认为是 100%。 +选项的默认值为 50%。集群管理员也可以在调度器的配置文件中,提供不同数值来做修改。 +但可能也并不需要修改这个值。 + +```yaml +apiVersion: componentconfig/v1alpha1 +kind: KubeSchedulerConfiguration +algorithmSource: + provider: DefaultProvider + +... + +percentageOfNodesToScore: 50 +``` + +{{< note >}} + + + +**注意**:如果集群中可行性节点的数量为 0 或者小于 50 个,调度器还是会检查所有的节点, +仅仅是因为没有足够多的可行性节点让调度器终止搜索。 + +{{< /note >}} + + + + +可以将 `percentageOfNodesToScore` 设置为 100 来**禁止这项功能**。 + + +### 调优 `percentageOfNodesToScore` + + + +`percentageOfNodesToScore` 的数值必须在 1 到 100 之间,默认值为 50。 +在内部设计里面,还存在有硬编码的至少 50 个节点的要求。无论 `percentageOfNodesToScore` 设置如何, +调度器都至少会搜索 50 个节点。换言之,在只有数百个节点的集群中调低这个参数,并不会对调度器搜索可行性节点有影响。 +这样设计是经过考虑的,因为在较小的集群中,这个参数并不会显著提升性能。 +而在超过 1000 个节点的大型集群中调低这个参数,将会有显著的性能提升。 + + + +在设置这个数值时,需要注意一点,如果集群中只有较少的一部分节点进行了可行性检查, +有些节点将不会被作可行性打分。 +因而,有运行 Pod 可行性分数更高的节点甚至可能不会到达打分阶段。这会造成一个并不十分理想的安排结果。 +正因为如此,这个数值不应该设置得非常低。 +一个重要原则就是这个数值不应该小于 30。 +更小的数值只应该在应用对调度器的吞吐量十分敏感,而节点的可行性打分相对不重要的前提下使用。 +换言之,只要节点适合运行 Pod 就可以安排到该节点上运行。 + + + +如果集群只有数百个节点,我们不建议将参数值调到比默认值低。因为这并不能显著提升调度器的性能。 + + +### 调度器是如何遍历节点的 + + + +这一节是为那些希望了解这项功能内部细节的人准备的。 + + + +为了让集群中所有的节点都有平等的机会被考虑运行 Pods,调度器需要以轮转的方式遍历所有的节点。 +你可以这样理解:所有节点都在记录在某数组之中,调度器从数组的一端开始检查节点的可行性,直到找到 `percentageOfNodesToScore` +指明的、足够多的节点。对于下一个 pod,调度器将从前一个 Pod 的结束节点开始,继续开始搜索。 + + + +如果节点在不同的区域,调度器也将遍历不同区域的所有节点,保证不同区域的节点都会被考虑在列。 +例如,如果六个节点分布在两个区域: + +``` +Zone 1: Node 1, Node 2, Node 3, Node 4 +Zone 2: Node 5, Node 6 +``` + + + +调度器将会按照下面的顺序来对所有的节点进行可行性检查: + +``` +Node 1, Node 5, Node 2, Node 6, Node 3, Node 4 +``` + + + +当遍历完所有的节点后,会重新从 Node 1 开始搜索。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/configuration/secret.md b/content/zh/docs/concepts/configuration/secret.md index a415bd5e00318..facc8d54eb5f9 100644 --- a/content/zh/docs/concepts/configuration/secret.md +++ b/content/zh/docs/concepts/configuration/secret.md @@ -547,13 +547,13 @@ spec: ### 客户端使用 Secret API -当部署与 secret API 交互的应用程序时,应使用诸如 [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) 之类的 [授权策略](https://kubernetes.io/docs/admin/authorization/) 来限制访问。 +当部署与 secret API 交互的应用程序时,应使用诸如 [RBAC](/docs/admin/authorization/rbac/) 之类的 [授权策略](/docs/admin/authorization/) 来限制访问。 Secret 中的值对于不同的环境来说重要性可能不同,例如对于 Kubernetes 集群内部(例如 service account 令牌)和集群外部来说就不一样。即使一个应用程序可以理解其期望的与之交互的 secret 有多大的能力,但是同一命名空间中的其他应用程序却可能不这样认为。 由于这些原因,在命名空间中 `watch` 和 `list` secret 的请求是非常强大的功能,应该避免这样的行为,因为列出 secret 可以让客户端检查所有 secret 是否在该命名空间中。在群集中`watch` 和 `list` 所有 secret 的能力应该只保留给最有特权的系统级组件。 -需要访问 secrets API 的应用程序应该根据他们需要的 secret 执行 `get` 请求。这允许管理员限制对所有 secret 的访问,同时设置 [白名单访问](https://kubernetes.io/docs/admin/authorization/rbac/#referring-to-resources) 应用程序需要的各个实例。 +需要访问 secrets API 的应用程序应该根据他们需要的 secret 执行 `get` 请求。这允许管理员限制对所有 secret 的访问,同时设置 [白名单访问](/docs/admin/authorization/rbac/#referring-to-resources) 应用程序需要的各个实例。 为了提高循环获取的性能,客户端可以设计引用 secret 的资源,然后 `watch` 资源,在引用更改时重新请求 secret。此外,还提出了一种 [”批量监控“ API](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/bulk_watch.md) 来让客户端 `watch` 每个资源,该功能可能会在将来的 Kubernetes 版本中提供。 diff --git a/content/zh/docs/concepts/configuration/taint-and-toleration.md b/content/zh/docs/concepts/configuration/taint-and-toleration.md index 388bb057c071a..b997b55df6854 100755 --- a/content/zh/docs/concepts/configuration/taint-and-toleration.md +++ b/content/zh/docs/concepts/configuration/taint-and-toleration.md @@ -78,7 +78,7 @@ To remove the taint added by the command above, you can run: --> 想删除上述命令添加的 taint ,您可以运行: ```shell -kubectl taint nodes kube11 key:NoSchedule- +kubectl taint nodes node1 key:NoSchedule- ``` ```yaml diff --git a/content/zh/docs/concepts/containers/_index.md b/content/zh/docs/concepts/containers/_index.md new file mode 100644 index 0000000000000..b17230af3a5ab --- /dev/null +++ b/content/zh/docs/concepts/containers/_index.md @@ -0,0 +1,11 @@ +--- +title: "容器" +weight: 50 +--- + + \ No newline at end of file diff --git a/content/zh/docs/concepts/containers/container-lifecycle-hooks.md b/content/zh/docs/concepts/containers/container-lifecycle-hooks.md new file mode 100644 index 0000000000000..1a7c51db72400 --- /dev/null +++ b/content/zh/docs/concepts/containers/container-lifecycle-hooks.md @@ -0,0 +1,229 @@ +--- +reviewers: +- mikedanese +- thockin +title: 容器生命周期钩子 +content_template: templates/concept +weight: 30 +--- + + + + +{{% capture overview %}} + + +这个页面描述了 kubelet 管理的容器如何使用容器生命周期钩子框架来运行在其管理生命周期中由事件触发的代码。 + +{{% /capture %}} + + +{{% capture body %}} + + + +## 概述 + + +类似于许多具有生命周期钩子组件的编程语言框架,例如Angular,Kubernetes为容器提供了生命周期钩子。 +钩子使容器能够了解其管理生命周期中的事件,并在执行相应的生命周期钩子时运行在处理程序中实现的代码。 + + + +## 容器钩子 + + +有两个钩子暴露在容器中: + +`PostStart` + + +这个钩子在创建容器之后立即执行。 +但是,不能保证钩子会在容器入口点之前执行。 +没有参数传递给处理程序。 + +`PreStop` + + +在容器终止之前立即调用此钩子。 +它是阻塞的,同时也是同步的,因此它必须在删除容器的调用之前完成。 +没有参数传递给处理程序。 + + +有关终止行为的更详细描述,请参见[终止 Pod](/docs/concepts/workloads/pods/pod/#termination-of-pods)。 + + + +### 钩子处理程序的实现 + + +容器可以通过实现和注册该钩子的处理程序来访问该钩子。 +针对容器,有两种类型的钩子处理程序可供实现: + + + +* Exec - 执行一个特定的命令,例如 `pre-stop.sh`,在容器的 cgroups 和名称空间中。 +命令所消耗的资源根据容器进行计算。 +* HTTP - 对容器上的特定端点执行 HTTP 请求。 + + + +### 钩子处理程序执行 + + +当调用容器生命周期管理钩子时,Kubernetes 管理系统在为该钩子注册的容器中执行处理程序。 + + +钩子处理程序调用在包含容器的 Pod 上下文中是同步的。 +这意味着对于 `PostStart` 钩子,容器入口点和钩子异步触发。 +但是,如果钩子运行或挂起的时间太长,则容器无法达到 `running` 状态。 + + +行为与 `PreStop` 钩子的行为类似。 +如果钩子在执行过程中挂起,Pod 阶段将保持在 `Terminating` 状态,并在 Pod 结束的 `terminationGracePeriodSeconds` 之后被杀死。 +如果 `PostStart` 或 `PreStop` 钩子失败,它会杀死容器。 + + +用户应该使他们的钩子处理程序尽可能的轻量级。 +但也需要考虑长时间运行的命令也很有用的情况,比如在停止容器之前保存状态。 + + + +### 钩子寄送保证 + + +钩子的寄送应该是*至少一次*,这意味着对于任何给定的事件,例如 `PostStart` 或 `PreStop`,钩子可以被调用多次。 +如何正确处理,是钩子实现所要考虑的问题。 + + +通常情况下,只会进行单次寄送。 +例如,如果 HTTP 钩子接收器宕机,无法接收流量,则不会尝试重新发送。 +然而,偶尔也会发生重复寄送的可能。 +例如,如果 kubelet 在发送钩子的过程中重新启动,钩子可能会在 kubelet 恢复后重新发送。 + + + +### 调试钩子处理程序 + + +钩子处理程序的日志不会在 Pod 事件中公开。 +如果处理程序由于某种原因失败,它将播放一个事件。 +对于 `PostStart`,这是 `FailedPostStartHook` 事件,对于 `PreStop`,这是 `FailedPreStopHook` 事件。 +您可以通过运行 `kubectl describe pod ` 命令来查看这些事件。 +下面是运行这个命令的一些事件输出示例: + +``` +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0" + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined] + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0" + 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567 + 38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1 + 37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1 + 38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1" + 1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook +``` + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* 了解更多关于[容器环境](/docs/concepts/containers/container-environment-variables/)。 +* 获取实践经验[将处理程序附加到容器生命周期事件](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/containers/images.md b/content/zh/docs/concepts/containers/images.md index 3f4e6a8acd398..6b48630b8dc2f 100644 --- a/content/zh/docs/concepts/containers/images.md +++ b/content/zh/docs/concepts/containers/images.md @@ -124,13 +124,13 @@ Docker将私有仓库的密钥存放在`$HOME/.dockercfg`或`$HOME/.docker/confi 推荐如下步骤来为node配置私有仓库。以下示例在PC或笔记本电脑中操作 - 1.对于想要使用的每一种凭证,运行 `docker login [server]`,它会更新`$HOME/.docker/config.json`。 - 1.使用编辑器查看`$HOME/.docker/config.json`,保证文件中包含了想要使用的凭证 - 1.获取node列表,例如 - - 如果使用node名称,`nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')` - - 如果使用node IP ,`nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')` - 1.将本地的`.docker/config.json`拷贝到每个节点root用户目录下 - - 例如: `for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done` + 1. 对于想要使用的每一种凭证,运行 `docker login [server]`,它会更新`$HOME/.docker/config.json`。 + 1. 使用编辑器查看`$HOME/.docker/config.json`,保证文件中包含了想要使用的凭证 + 1. 获取node列表,例如 + - 如果使用node名称,`nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')` + - 如果使用node IP ,`nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')` + 1. 将本地的`.docker/config.json`拷贝到每个节点root用户目录下 + - 例如: `for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done` 创建使用私有仓库的pod来验证,例如: diff --git a/content/zh/docs/concepts/containers/runtime-class.md b/content/zh/docs/concepts/containers/runtime-class.md new file mode 100644 index 0000000000000..4029826901f0d --- /dev/null +++ b/content/zh/docs/concepts/containers/runtime-class.md @@ -0,0 +1,197 @@ +--- +reviewers: +- tallclair +- dchen1107 +title: RuntimeClass +content_template: templates/concept +weight: 20 +--- + +{{% capture overview %}} + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + + +本页面讨论了 RuntimeClass 资源和运行时的选择机制。 + +{{% /capture %}} + +{{< toc >}} + +{{% capture body %}} + +## RuntimeClass + + +RuntimeClass 是一个 alpha 功能,用来选择运行 pod 中容器的容器运行时配置。 + + +### 设置 + + +作为一个处于早期状态的 alpha 特性,必须要完成以下步骤才能使用 RuntimeClass 功能: + + +1. 开启 RuntimeClass 特性门控(在 apiservers & kubelets 上,需要 1.12 及以上版本) +2. 安装 RuntimeClass CRD +3. 在节点上配置 CRI 的实现(取决于所选的运行时) +4. 创建相应的 RuntimeClass 资源 + + +#### 1. 开启 RuntimeClass 特性门控 + + +参见[特性门控](/docs/reference/command-line-tools-reference/feature-gates/)文档了解如何开启特定的特性门控。 +`RuntimeClass` 特性门控必须在 apiservers _和_ kubelets 上同时开启,才能使用。 + + +#### 2. 安装 RuntimeClass CRD + + +可以在 Kubernetes git 仓库的 addons 目录中找到 +RuntimeClass [CustomResourceDefinition (CRD)](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/) 的定义: + +https://github.com/kubernetes/kubernetes/tree/release-1.12/cluster/addons/runtimeclass/runtimeclass_crd.yaml + + + +使用 `kubectl apply -f runtimeclass_crd.yaml` 命令安装 CRD。 + + +#### 3. 在节点上配置 CRI 实现 + + +各 RuntimeClass 所支持的配置选项取决于 CRI 的实现本身。 +请参阅 CRI 实现的相应文档了解具体如何配置。 +由于这是一个 alpha 特性功能,并非所有 CRI 都支持多个 RuntimeClass。 + + +{{< note >}} +RuntimeClass 当前假设的是集群中的节点配置是同构的(换言之,所有的节点在容器运行时方面的配置是相同的)。 +任何异构性(不同的配置)必须通过调度功能在 RuntimeClass 之外单独管理(请参阅[在节点上分配 Pods](/docs/concepts/configuration/assign-pod-node/))。 +{{< /note >}} + + +所有这些配置都具有相应的 `RuntimeHandler` 名,并被 RuntimeClass 引用。 +RuntimeHandler 必须是有效的 DNS-1123 子域(字母数字字符、`-` 或 `.`)。 + + + +#### 4. 创建相应的 RuntimeClass 资源 + + +步骤 3 中的配置设置应该有相应的 `RuntimeHandler` 名,用于标识配置。 +对应每个 RuntimeHandler(以及 `""` 所代表的空处理程序),都创建相应的 RuntimeClass 对象。 + + +RuntimeClass 资源当前只有两个重要的字段:RuntimeClass 名 (`metadata.name`) 和 RuntimeHandler (`spec.runtimeHandler`)。 +对象定义如下所示: + +```yaml +apiVersion: node.k8s.io/v1alpha1 # 在 node.k8s.io API 中对 RuntimeClass 进行定义 +kind: RuntimeClass +metadata: + name: myclass # 引用 RuntimeClass + # RuntimeClass 是不属于任何名字空间的资源 +spec: + runtimeHandler: myconfiguration # 给出 CRI 配置的名称 +``` + + + +{{< note >}} +建议将 RuntimeClass 写操作(create、update、patch 和 delete)限定于集群管理员使用。 +通常这是默认配置。参阅[授权概述](/docs/reference/access-authn-authz/authorization/)了解更多信息。 +{{< /note >}} + + + +### 使用说明 + +一旦完成集群中 RuntimeClasses 的配置,使用起来非常简便。 +在 Pod spec 中指定 `runtimeClassName` 即可。例如: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + runtimeClassName: myclass + # ... +``` + + + +这一设置会告诉 Kubelet 使用所指的 RuntimeClass 来运行该 pod。 +如果所指的 RuntimeClass 不存在或者 CRI 无法运行相应的 handler,那么 pod 将会进入 `Failed` 终止[阶段](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)。 +你可以查看相应的[事件](/docs/tasks/debug-application-cluster/debug-application-introspection/),获取出错信息。 + + +如果未指定 `runtimeClassName` ,则将使用默认的 RuntimeHandler,相当于禁用 RuntimeClass 功能特性。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/extend-kubernetes/_index.md b/content/zh/docs/concepts/extend-kubernetes/_index.md new file mode 100644 index 0000000000000..9eef5fffc5f54 --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/_index.md @@ -0,0 +1,11 @@ +--- +title: 扩展 Kubernetes +weight: 40 +--- + + diff --git a/content/zh/docs/concepts/extend-kubernetes/api-extension/_index.md b/content/zh/docs/concepts/extend-kubernetes/api-extension/_index.md new file mode 100644 index 0000000000000..51c5bdcc7ac70 --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/api-extension/_index.md @@ -0,0 +1,11 @@ +--- +title: 扩展 Kubernetes API +weight: 20 +--- + + diff --git a/content/zh/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation.md b/content/zh/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation.md new file mode 100644 index 0000000000000..11dc1e423aced --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation.md @@ -0,0 +1,73 @@ + + +--- +title: 通过聚合层扩展 Kubernetes API +reviewers: +- lavalamp +- cheftako +- chenopis +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} + + + +聚合层允许 Kubernetes 通过额外的 API 进行扩展,而不局限于 Kubernetes 核心 API 提供的功能。 + +{{% /capture %}} + +{{% capture body %}} + + + +## 概述 + +聚合层使您的集群可以安装其他 Kubernetes 风格的 API。这些 API 可以是预编译的、第三方的解决方案提供的例如[service-catalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/README.md)、或者用户创建的类似[apiserver-builder](https://github.com/kubernetes-incubator/apiserver-builder/blob/master/README.md)一样的API可以帮助你上手。 + + + +1.7 版本中,聚合层在 kube-apiserver 进程内运行。在扩展资源注册之前,聚合层不做任何事情。要注册 API,用户必须添加一个 APIService 对象,用它来申领 Kubernetes API 中的 URL 路径。自此以后,聚合层将会把发给该 API 路径的所有内容(例如 /apis/myextension.mycompany.io/v1/…)代理到已注册的 APIService。 + + + +正常情况下,APIService 会实现为运行于集群中某 Pod 内的 extension-apiserver。如果需要对增加的资源进行动态管理,extension-apiserver 经常需要和一个或多个控制器一起使用。因此,apiserver-builder 同时提供用来管理新资源的 API 框架和控制器框架。另外一个例子,当安装了 service-catalog 时,它会为自己提供的服务提供 extension-apiserver 和控制器。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* 阅读[配置聚合层](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) 文档,了解如何在自己的环境中启用聚合器(aggregator)。 +* 然后[安装扩展的 api-server](/docs/tasks/access-kubernetes-api/setup-extension-api-server/) 来开始使用聚合层。 +* 也可以学习怎样 [使用客户资源定义扩展 Kubernetes API](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)。 + +{{% /capture %}} + + diff --git a/content/zh/docs/concepts/extend-kubernetes/api-extension/custom_resources.md b/content/zh/docs/concepts/extend-kubernetes/api-extension/custom_resources.md new file mode 100644 index 0000000000000..bee484cb16cde --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/api-extension/custom_resources.md @@ -0,0 +1,535 @@ +--- +title: 自定义资源 +reviewers: +- enisoc +- deads2k +content_template: templates/concept +weight: 20 +--- + + +{{% capture overview %}} + + +*自定义资源* 是 Kubernetes API 的扩展。本页讨论何时向 Kubernetes 群集添加自定义资源以及何时使用独立服务。它描述了添加自定义资源的两种方法以及如何在它们之间进行选择。 + +{{% /capture %}} + +{{% capture body %}} + +## 自定义资源 + + +*资源* 是[Kubernetes API](/docs/reference/using-api/api-overview/)中的端点,用于存储 +某种[API 对象](/docs/concepts/overview/working-with-objects/kubernetes-objects/)的集合。例如,内置 *Pod* 资源包含 Pod 对象的集合。 + + +*自定义资源* 是 Kubernetes API 的扩展,在 Kubernetes 的默认安装中不一定可用。它使 Kubernetes 具备可定制化安装的能力。但是,很多核心 Kubernetes 功能现在都使用自定义资源构建,使 Kubernetes 模块更加合理。 + + +自定义资源可以通过动态注册在运行的集群中显示或者消失,并且集群管理员可以独立于集群本身更新自定义资源。安装自定义资源后,用户可以使用 [kubectl](/docs/user-guide/kubectl-overview/) 创建和访问其对象,就像对 *Pod* 等内置资源一样。 + + +## 自定义控制器 + + +自定义资源可以存储和检索结构化数据。将自定义资源和自定义控制器结合时,自定义资源提供一个真正 _声明式 API_ 。 + + +[声明式 API](/docs/concepts/overview/working-with-objects/kubernetes-objects/#understanding-kubernetes-objects) 允许使用者_声明_或者指定所需的资源状态,并使当前状态与预期状态保持一致。控制器将结构化数据解释为用户所需状态的记录,并持续维护此状态。 + + +你可以在运行中的集群上部署或更新自定义控制器,而这一操作是与集群自身的生命期无关的。自定义控制器可以与任何资源一起工作,但是与自定义资源相结合时他们特别有效。[ Operator 模式](https://coreos.com/blog/introducing-operators.html) 结合了自定义资源和自定义控制器。您可以使用自定义控制器将特定应用程序的领域知识编码到 Kubernetes API 的扩展中。 + + +## 是否需要向 Kubernetes 集群添加自定义资源? + + +创建新 API 的时候,请考虑是[将 API 与 Kubernetes 集群 API 聚合](/docs/concepts/api-extension/apiserver-aggregation/) 还是将API独立。 + + +| 如果属于下面情况之一,可以考虑采用 API 聚合: | 如果属于下面情况之一,首选独立 API : | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| API 具有[声明性](#declarative-apis). | API 不适合[声明性](#declarative-apis)模型. | +| 你希望可使用 `kubectl` 来读写新类型。 | 不需要 `kubectl` 支持 | +| 你希望在 Kubernetes 用户界面(如 dashboard)中和内置类型一起看到你的新类型。 | 不需要 Kubernetes 使用界面支持。 | +| 你正在开发新的 API。 | 你已经有一个运行良好的程序为你提供 API 服务。 | +| 你愿意接受 Kubernetes 对 REST 资源路径的格式限制,例如 API 组和命名空间。 (参照 [API 概述](/docs/concepts/overview/kubernetes-api/).) | 你需要有一个特定的 REST 路径来兼容已经定义的 REST API 。 | +| 你的资源可以很自然地归入集群作用域或者集群中的某个命名空间的作用域。 | 集群或者命名空间作用域均不合适;你需要控制资源路径的细节。 | +| 你希望重用 [Kubernetes API 的支持功能](#common-features). | 你不需要这些功能。 | + + +### 声明式 API {#declarative-apis} + + +在声明式 API 中,通常: + + + - API由相对较少的对象(资源)组成。 + - 对象定义了应用或基础设施的配置项。 + - 对象更新相对较少。 + - 用户经常需要读取和写入对象。 + - 对象上的主要操作是 CRUD(创建,读取,更新和删除)。 + - 不需要跨对象的事务:API 表示一个所需的状态,而不是一个确切的状态。 + + +命令式 API 不是声明式的。API 不是声明式的特点包括: + + + - 客户端说“执行此操作”,然后在完成时获取同步响应。 + - 客户端说“执行此操作”,然后获取一个操作 ID,并且为了确认请求的完成,必须检查单独的操作对象。 + - 说的是远程过程调用(RPCs)。 + - 直接存储大量数据(例如,每个对象几 kB,或1000个对象)。 + - 需要高带宽访问(每秒持续的10个请求) + - 存储业务用户数据(如图像、PII 等)或者其他由应用程序处理的大规模数据。 + - 对于对象的自然操作不是 CRUD。 + - API 不容易建模成对象。 + - 你选择使用操作 ID 或者操作对象来表示待解决的操作。 + + +## 我应该使用 configMap 还是自定义资源? + + +如果以下任何一项适用,请使用 ConfigMap : + + +* 存在一种记录良好的配置文件格式,,例如 `mysql.cnf` 或者 `pom.xml` 。 +* 你想把所有的配置文件都放进 configMap 的一个键中。 +* 配置文件的作用就是,让运行在集群中 Pod 的程序配置自身环境。 +* 文件使用者更倾向于使用通过 Pod 中的文件或 Pod 中的环境变量,而不是使用 Kubernetes API。 +* 你希望在更新文件时通过部署等执行滚动更新。 + + +{{< note >}} +对敏感数据使用 [secret](/docs/concepts/configuration/secret/) , 类似于 configMap ,但更安全。 +{{}} + + +如果以下大多数情况出现,请使用自定义资源( CustomResourceDefinition 或者 API集合 ): + + +* 您希望使用 Kubernetes 客户端库和 CLIs 来创建和更新新资源。 +* 你希望从 kubectl 得到顶级支持(比如:`kubectl get my-object object-name`)。 +* 你希望新建一个自动化以监视新对象的更新,然后监视 CRUD 其他对象,反之亦然。 +* 你希望编写处理对象更新的自动化。 +* 你想要使用 Kubernetes API约定,比如像 `.spec` , `.status` ,和 `.metadata` 。 +* 你希望对象是受控资源集合的抽象,或者是其他资源的汇总。 + + +## 添加自定义资源 + + +Kubernetes 提供了两种将自定义资源添加到集群的方法: + + +- CustomResourceDefinition 非常简单,无需任何编程即可创建。 +- [API 聚集](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)需要编程,但允许对 API 行为进行更多控制,比如数据的存储方式和 API 版本之间的转换。 + + +Kubernetes 提供了两个选项来满足不同使用者的需要,因此无论是易用性还是灵活性都不受影响。 + + +API 聚集是位于主API服务器后面的从属 API 服务器,用来充当代理。这种安排被称作[API 聚合](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) (AA)。对于用户来说,Kubernetes API 似乎只是扩展了。 + + +CustomResourceDefinition 允许用户在不添加其他 API 服务器的情况下创建新类型的资源。您无需了解 API 集合就可以使用 CustomResourceDefinition 。 + + +无论如何安装,新资源都被称为自定义资源,已将其与内置的 Kubernetes(如 Pod )资源区分开。 + + +## 自定义资源定义(CustomResourceDefinition) {#CustomResourceDefinition} + + +[CustomResourceDefinition](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/) API 资源允许你去定义自定义资源。定义 CustomResourceDefinition 对象创建了一个新的自定义资源,该资源具有您指定的名称和架构。Kubernetes API 提供并处理自定义资源的存储。 + + +这样,你就不用为了处理自定义资源来编写你自己的API服务器了,但是实现的通用性意味着比 [API 服务器集合](#api-server-aggregation)的灵活性要低。 + + +有关如何注册新自定义资源、使用新资源类型的实例以及使用控制器处理事件的示例,请参阅[自定义控制器示例](https://github.com/kubernetes/sample-controller)。 + + +## API服务器聚合 + + +通常,Kubernetes API 中的每个资源都需要代码来处理 REST 请求和管理对象的持续存储。主 Kubernetes API服务器处理像 *Pod* 和 *services* 的内置资源,还可以通过 [CustomResourceDefinition](#customresourcedefinitions) 以通用的方式处理自定义资源。 + + +[集合层](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)允许您通过编写部署你自己独立的API服务器来为自定义资源提供专用实现。 + + +主 API 服务器将委托您处理自定义资源,使其可供所有客户端使用。 + + +## 选择添加自定义资源的方法 + + +CustomResourceDefinition 更易于使用。API 集合更加灵活。选择更能满足您需求的方法。 + + +通常,CustomResourceDefinition 更适合以下几个方面: + + +* 你有几个字段。 +* 你正在使用公司内的资源,或者一个小的开源项目的一部分(区别于商业产品) + + +### 比较易用性 + + +CustomResourceDefinition 比 API 集合更容易创建。 + + +| CustomResourceDefinition(CRD) | API 集合 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| 不需要编程。用户可以为 CRD 控制器选择任何语言。 | 需要在 Go 中编程并构建二进制和镜像。用户可以为CRD控制器选择任何语言。 | +| 无需运行其他服务; CR 由 API 服务器处理。 | 要创建其他服务,并可以会失败。 | +| 一旦 CRD 创建,无需后续支持。任何错误修复都是正常 Kubernetes Master 升级的一部分。 | 可能需要定期从上游拾取错误修复,并重建和更新 API 集合服务器。 | +| 无需处理 API 的多个版本。例如:当您控制此资源的客户端时,可以将其与 API 同步升级。 | 你需要处理 API 的多个版本,例如:当开发一个扩展,与世界分享时。 | + + +### 高级功能和灵活性 + + +API 集合提供更高级的 API 特性以及其他功能的自定义,例如:存储层。 + + +| 特性 | 描述 | CustomResourceDefinition | API集合 | +| ------- | ----------- | ---- | -------------- | +| 验证 |帮助用户避免错误并且允许您独立于客户端发展API。 当有许多客户端无法同时更新时,这些功能非常有用。 | 是的。大多数验证可以在CustomResourceDefinition 中使用[OpenAPI v3.0 validation](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#validation)来验证。 其他验证可以通过添加[验证的 Webhook](/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook-alpha-in-1-8-beta-in-1-9)来支持. | 是的,任意验证检查。 | +| 违约 | 见上文 | 是的, 通过 [突变的 Webhook](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook-beta-in-1-9); 规划, 通过 CustomResourceDefinition OpenAPI 架构. | 是的 | +| 多版本 | 允许通过两个 API 版本为同一对象提供服务。 可帮助简化 API 更改,如重命名字段。 如果您控制客户端版本,则不太重要。| [是的](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning) | 是的 | +| 自定义存储 | 如果需要不同性能模式的存储(例如,时间序列数据库而不是密钥值存储) 或为了安全进行隔离(例如,加密机密或不同的)| 不是 | 是的 | +| 定制业务逻辑 | 在创建,读取,更新或删除对象时执行任意检查或操作 | 是的, 使用 [Webhooks](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)。| 是的 | +| Scale 子资源 | 允许 HorizontalPodAutoscaler 和 PodDisruptionBudget 与您的新资源进行互换 | [是的](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#scale-subresource) | 是的 | +| Status 子资源 |
  • 细粒度访问控制:用户写入规范部分,控制器写入状态部分。
  • 允许递增对象在自定义资源数据突变上 Generation (需要资源中的单独规范和状态部分)
| [是的](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#status-subresource) | 是的 | +| 其他子资源| 添加 CRUD 以外的操作,如"日志"或"执行"。 | 不是 | 是的 | +| 战略-合并-补丁 | 新的端点支持具有 `Content-Type: application/strategic-merge-patch+json` 的 PATCH . 可用于更新可在本地和服务器修改的对象。更多信息,请参阅["使用 kubectl 修补程序更新API对象"](/docs/tasks/run-application/update-api-object-kubectl-patch/) | 不是 | 是的 | +| 协议缓冲区 | 新资源支持希望使用协议缓冲区的客户端 | 不是 | 是的 | +| OpenAPI 架构 | 是否有可从服务器动态提取类型的 OpenAPI (swagger) 架构?用户通过确保只设置允许的字段来避免拼写错误的字段名称是否被设置? 是否是强制执行类型 (换句话说,不要在 `string` 字段中放置 `int` ?) | 不,但有计划 | 是的 | + + +### 公共特性 + + +与在 Kubernetes 平台之外实现它相比,当通过 CustomResourceDefinition 或 AA 创建自定义资源时,您可以获得 API 的许多功能: + + + +| 功能 | 作用 | +| ------- | ------------ | +| CRUD | 通过 HTTP 和 `kubectl` ,新的端点通过 HTTP 和 kubectl 支持 CRUD 基本操作| +| Watch | 新的端点通过 HTTP 支持 Kubernetes 监视功能 | +| 发现 | 如 Kubectl 和 dashboard 客户端会自动提供资源上的列表、显示和字段编辑操作 | +| json-patch | 新的端点支持打上 `Content-Type: application/json-patch+json` 的 PATCH | +| merge-patch | 新的端点支持打上 `Content-Type: application/merge-patch+json` 的 PATCH | +| HTTPS | 新的端点使用 HTTPS | +| 内置身份验证 | 对扩展的访问使用核心API服务(聚合层)进行身份认证 | +| 内置授权 | 对扩展的访问可以重用被核心API服务使用的授权(例如,基于角色的访问控制 role-based access control) | +| 终结器 | 阻止删除扩展资源,直到进行外部清理。| +| 准入 Webhooks | 在任何创建/更新/删除操作期间设置默认值并验证扩展资源。 | +| UI/CLI 显示 | Kubectl ,和 dashboard 可以显示扩展资源。| +| 未设置与空 | 客户端可以把未设置字段从零值字段中区分出来。 | +| 客户端库生成 | Kubernetes 提供通用客户端库,以及用于生成特定客户端库的工具。| +| 标签和注释 | 工具知道如何编辑核心和自定义资源的跨对象的通用元数据 | + + +## 准备安装自定义资源 + + +在将自定义资源添加到群集之前,需要注意几个要点。 + + +### 第三方代码和新的故障点 + + +虽然创建CRD不会自动添加任何新的故障点(例如,通过第三方代码在 API 服务器上运行),但包(例如,图表)或其他安装捆绑包经常包括 CustomResourceDefinition 以及 Deployment 第三方代码来实现新的自定义资源的业务逻辑。 + + +安装新的聚合 API 服务器总是涉及运行新的部署。 + + +### 存储 + +自定义资源与 ConfigMap 以相同的方式消耗存储空间。创建过多的自定义资源会过载 API 服务器的存储空间。 + + +API 集合服务器可以使用与主 API 服务器相同的存储,在这种情况下,将应用相同的警告。 + + +### 身份验证、授权和审核 + + +CustomResourceDefinition 始终使用与 API 服务器内置资源相同的身份验证、授权和审核日志记录。 + + +如果使用 RBAC 进行授权,大多数 RBAC (基于角色的访问控制)的角色不会授予对新资源的访问权限(除了集群管理员角色或任何通配符规则创建的角色)。您需要明确授予对新资源的访问权限。CustomResourceDefinition 和 API集合 通常与他们添加类型的新角色定义捆绑。 + + +API 集合服务器可能使用或不使用与主 API 服务器相同的身份验证,授权和审核。 + + +## 访问自定义资源 + + +Kubernetes [客户端库](/docs/reference/using-api/client-libraries/)可用于访问自定义资源。并非所有客户端库都支持自定义资源。go 和 python 客户端库可以。 + + +当你添加了一个自定义资源,可以使用一下命令来访问它: + + +- kubectl +- kubernetes 动态客户端。 +- 你编写的 REST 客户端。 +- 使用 Kubernetes [客户端生成工具](https://github.com/kubernetes/code-generator)生成的客户端(生成是一个高级的任务,但有些项目可能会提供客户端以及 CustomResourceDdfinition 或 Aggregated API ) + +{{% /capture %}} + +{{% capture whatsnext %}} + + +* 了解如何使用[聚合层扩展 Kubernetes API](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)。 + + +* 了解如何使用 [CustomResourceDefinition 扩展 Kubernetes API](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)。 + +{{% /capture %}} + diff --git a/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/_index.md b/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/_index.md new file mode 100644 index 0000000000000..1b46b18dd2a52 --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/_index.md @@ -0,0 +1,11 @@ +--- +title: 计算、存储和网络扩展 +weight: 30 +--- + + diff --git a/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins.md b/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins.md new file mode 100644 index 0000000000000..506539c3bef67 --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins.md @@ -0,0 +1,273 @@ +--- +title: 网络插件 +content_template: templates/concept +weight: 10 +--- + + + +{{% capture overview %}} + +{{< feature-state state="alpha" >}} + +{{< warning >}}Alpha 特性迅速变化。{{< /warning >}} + + +Kubernetes中的网络插件有几种类型: + +* CNI 插件: 遵守 appc/CNI 规约,为互操作性设计。 +* Kubenet 插件:使用 `bridge` 和 `host-local` CNI 插件实现了基本的 `cbr0`。 + +{{% /capture %}} + +{{% capture body %}} + + +## 安装 + +kubelet 有一个单独的默认网络插件,以及一个对整个集群通用的默认网络。 +它在启动时探测插件,记住找到的内容,并在 pod 生命周期的适当时间执行所选插件(这仅适用于 Docker,因为 rkt 管理自己的 CNI 插件)。 +在使用插件时,需要记住两个 Kubelet 命令行参数: + +* `cni-bin-dir`: Kubelet 在启动时探测这个目录中的插件 +* `network-plugin`: 要使用的网络插件来自 `cni-bin-dir`。它必须与从插件目录探测到的插件报告的名称匹配。对于 CNI 插件,其值为 "cni"。 + + +## 网络插件要求 + +除了提供[`NetworkPlugin` 接口](https://github.com/kubernetes/kubernetes/tree/{{< param "fullversion" >}}/pkg/kubelet/dockershim/network/plugins.go)来配置和清理 pod 网络之外,该插件还可能需要对 kube-proxy 的特定支持。 +iptables 代理显然依赖于 iptables,插件可能需要确保 iptables 能够监控容器的网络通信。 +例如,如果插件将容器连接到 Linux 网桥,插件必须将 `net/bridge/bridge-nf-call-iptables` 系统参数设置为`1`,以确保 iptables 代理正常工作。 +如果插件不使用 Linux 网桥(而是类似于 Open vSwitch 或者其它一些机制),它应该确保为代理对容器通信执行正确的路由。 + +默认情况下,如果未指定 kubelet 网络插件,则使用 `noop` 插件,该插件设置 `net/bridge/bridge-nf-call-iptables=1`,以确保简单的配置(如带网桥的 Docker )与 iptables 代理正常工作。 + + +### CNI + +通过给 Kubelet 传递 `--network-plugin=cni` 命令行选项来选择 CNI 插件。 +Kubelet 从 `--cni-conf-dir` (默认是 `/etc/cni/net.d`) 读取文件并使用该文件中的 CNI 配置来设置每个 pod 的网络。 +CNI 配置文件必须与 [CNI 规约](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration)匹配,并且配置引用的任何所需的 CNI 插件都必须存在于 `--cni-bin-dir`(默认是 `/opt/cni/bin`)。 + +如果这个目录中有多个 CNI 配置文件,则使用按文件名的字典顺序排列的第一个配置文件。 + +除了配置文件指定的 CNI 插件外,Kubernetes 还需要标准的 CNI [`lo`](https://github.com/containernetworking/plugins/blob/master/plugins/main/loopback/loopback.go) 插件,最低版本是0.2.0。 + + +#### 支持 hostPort + +CNI 网络插件支持 `hostPort`。 您可以使用官方 [portmap](https://github.com/containernetworking/plugins/tree/master/plugins/meta/portmap) +插件,它由 CNI 插件团队提供,或者使用您自己的带有 portMapping 功能的插件。 + +如果你想要启动 `hostPort` 支持,则必须在 `cni-conf-dir` 指定 `portMappings capability`。 +例如: + +```json +{ + "name": "k8s-pod-network", + "cniVersion": "0.3.0", + "plugins": [ + { + "type": "calico", + "log_level": "info", + "datastore_type": "kubernetes", + "nodename": "127.0.0.1", + "ipam": { + "type": "host-local", + "subnet": "usePodCidr" + }, + "policy": { + "type": "k8s" + }, + "kubernetes": { + "kubeconfig": "/etc/cni/net.d/calico-kubeconfig" + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] +} +``` + + +#### 支持流量整形 + +CNI 网络插件还支持 pod 入口和出口流量整形。 +您可以使用 CNI 插件团队提供的 [bandwidth](https://github.com/containernetworking/plugins/tree/master/plugins/meta/bandwidth) 插件, +也可以使用您自己的具有带宽控制功能的插件。 + +如果您想要启用流量整形支持,你必须将 `bandwidth` 插件添加到 CNI 配置文件 +(默认是 `/etc/cni/net.d`)。 + +```json +{ + "name": "k8s-pod-network", + "cniVersion": "0.3.0", + "plugins": [ + { + "type": "calico", + "log_level": "info", + "datastore_type": "kubernetes", + "nodename": "127.0.0.1", + "ipam": { + "type": "host-local", + "subnet": "usePodCidr" + }, + "policy": { + "type": "k8s" + }, + "kubernetes": { + "kubeconfig": "/etc/cni/net.d/calico-kubeconfig" + } + }, + { + "type": "bandwidth", + "capabilities": {"bandwidth": true} + } + ] +} +``` + +现在,您可以将 `kubernetes.io/ingress-bandwidth` 和 `kubernetes.io/egress-bandwidth` 注解添加到 pod 中。 +例如: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + annotations: + kubernetes.io/ingress-bandwidth: 1M + kubernetes.io/egress-bandwidth: 1M +... +``` + + +### kubenet + +Kubenet 是一个非常基本的、简单的网络插件,仅适用于 Linux。 +它本身并不实现更高级的功能,如跨节点网络或网络策略。 +它通常与云驱动一起使用,云驱动为节点间或单节点环境中的通信设置路由规则。 + +Kubenet 创建名为 `cbr0` 的网桥,并为每个 pod 创建了一个 veth 对,每个 pod 的主机端都连接到 `cbr0`。 +这个 veth 对的 pod 端会被分配一个 IP 地址,该 IP 地址隶属于节点所被分配的 IP 地址范围内。节点的 IP 地址范围则通过配置或控制器管理器来设置。 +`cbr0` 被分配一个 MTU,该 MTU 匹配主机上已启用的正常接口的最小 MTU。 + +使用此插件还需要一些其他条件: + +* 需要标准的 CNI `bridge`、`lo` 以及 `host-local` 插件,最低版本是0.2.0。Kubenet 首先在 `/opt/cni/bin` 中搜索它们。 指定 `cni-bin-dir` 以提供其它的搜索路径。首次找到的匹配将生效。 +* Kubelet 必须和 `--network-plugin=kubenet` 参数一起运行,才能启用该插件。 +* Kubelet 还应该和 `--non-masquerade-cidr=` 参数一起运行,以确保超出此范围的 IP 流量将使用 IP 伪装。 +* 节点必须被分配一个 IP 子网,通过kubelet 命令行的 `--pod-cidr` 选项或控制器管理器的命令行选项 `--allocate-node-cidrs=true --cluster-cidr=` 来设置。 + + +### 自定义 MTU(使用 kubenet) + +要获得最佳的网络性能,必须确保 MTU 的取值配置正确。 +网络插件通常会尝试推断出一个合理的 MTU,但有时候这个逻辑不会产生一个最优的 MTU。 +例如,如果 Docker 网桥或其他接口有一个小的 MTU, kubenet 当前将选择该 MTU。 +或者如果您正在使用 IPSEC 封装,则必须减少 MTU,并且这种计算超出了大多数网络插件的能力范围。 + +如果需要,您可以使用 `network-plugin-mtu` kubelet 选项显式的指定 MTU。 +例如:在 AWS 上 `eth0` MTU 通常是 9001,因此您可以指定 `--network-plugin-mtu=9001`。 +如果您正在使用 IPSEC ,您可以减少它以允许封装开销,例如 `--network-plugin-mtu=8873`。 + +此选项会传递给网络插件; 当前 **仅 kubenet 支持 `network-plugin-mtu`**。 + + +## 使用总结 + +* `--network-plugin=cni` 用来表明我们要使用 `cni` 网络插件,实际的 CNI 插件可执行文件位于 `--cni-bin-dir`(默认是 `/opt/cni/bin`)下, CNI 插件配置位于 `--cni-conf-dir`(默认是 `/etc/cni/net.d`)下。 +* `--network-plugin=kubenet` 用来表明我们要使用 `kubenet` 网络插件,CNI `bridge` 和 `host-local` 插件位于 `/opt/cni/bin` 或 `cni-bin-dir` 中。 +* `--network-plugin-mtu=9001` 指定了我们使用的 MTU,当前仅被 `kubenet` 网络插件使用。 + +{{% /capture %}} + +{{% capture whatsnext %}} + +{{% /capture %}} diff --git a/content/zh/docs/concepts/extend-kubernetes/extend-cluster.md b/content/zh/docs/concepts/extend-kubernetes/extend-cluster.md new file mode 100644 index 0000000000000..a5af58004924d --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/extend-cluster.md @@ -0,0 +1,371 @@ +--- +title: 扩展你的 Kubernetes 集群 +reviewers: +- erictune +- lavalamp +- cheftako +- chenopis +content_template: templates/concept +weight: 10 +--- + + + +{{% capture overview %}} + + +Kubernetes 是高度可配置和可扩展的。因此,极少需要分发或提交补丁代码给 Kubernetes 项目。 + +本文档介绍自定义 Kubernetes 集群的选项。本文档的目标读者是希望了解如何使 Kubernetes 集群满足其业务环境需求的集群运维人员。Kubernetes 项目的贡献者或潜在的平台开发人员也可以从本文找到有用的信息,如对已存在扩展点和模式的介绍,以及它们的权衡和限制。 + +{{% /capture %}} + + +{{% capture body %}} + + +## 概述 + +定制方法可以大致分为 *配置* 和 *扩展* 。*配置* 只涉及更改标志参数,本地配置文件或 API 资源; *扩展* 涉及运行额外的程序或服务。本文档主要内容是关于扩展。 + + +## 配置 + +关于 *配置文件* 和 *标志* 的说明文档位于在线文档的参考部分,按照二进制组件各自描述: + +* [kubelet](/docs/admin/kubelet/) +* [kube-apiserver](/docs/admin/kube-apiserver/) +* [kube-controller-manager](/docs/admin/kube-controller-manager/) +* [kube-scheduler](/docs/admin/kube-scheduler/). + +在托管的 Kubernetes 服务或受控安装的 Kubernetes 版本中,标志和配置文件可能并不总是可以更改的。而且当它们可以进行更改时,它们通常只能由集群管理员进行更改。此外,标志和配置文件在未来的 Kubernetes 版本中可能会发生变化,并且更改设置后它们可能需要重新启动进程。出于这些原因,只有在没有其他选择的情况下才使用它们。 + + *内置策略 API* ,例如 [ResourceQuota](/docs/concepts/policy/resource-quotas/)、[PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/)、[NetworkPolicy](/docs/concepts/services-networking/network-policies/) 和基于角色的权限控制 ([RBAC](/docs/reference/access-authn-authz/rbac/)),是内置的 Kubernetes API。API 通常与托管的 Kubernetes 服务和受控的 Kubernetes 安装一起使用。 +它们是声明性的,并使用与其他 Kubernetes 资源(如 Pod )相同的约定,所以新的集群配置可以重复使用,并以与应用程序相同的方式进行管理。而且,当他们变稳定后,他们和其他 Kubernetes API 一样享受[定义支持政策](/docs/reference/deprecation-policy/)。出于这些原因,在合适的情况下它们优先于 *配置文件* 和 *标志* 被使用。 + + +## 扩展程序 + +扩展程序是指对 Kubernetes 进行扩展和深度集成的软件组件。它们适合用于支持新的类型和新型硬件。 + +大多数集群管理员会使用托管的或统一分发的 Kubernetes 实例。因此,大多数 Kubernetes 用户需要安装扩展程序,而且还有少部分用户甚至需要编写新的扩展程序。 + + +## 扩展模式 + +Kubernetes 的设计是通过编写客户端程序来实现自动化的。任何读和(或)写 Kubernetes API 的程序都可以提供有用的自动化工作。 *自动化* 程序可以运行在集群之中或之外。按照本文档的指导,您可以编写出高可用的和健壮的自动化程序。自动化程序通常适用于任何 Kubernetes 集群,包括托管集群和受管理安装的集群。 + +*控制器* 模式是编写适合 Kubernetes 的客户端程序的一种特定模式。控制器通常读取一个对象的 `.spec` 字段,可能做出一些处理,然后更新对象的 `.status` 字段。 + +一个控制器是 Kubernetes 的一个客户端。而当 Kubernetes 作为客户端调用远程服务时,它被称为 *Webhook* ,远程服务称为 *Webhook* 后端。 和控制器类似,Webhooks 增加了一个失败点。 + +在 webhook 模型里,Kubernetes 向远程服务发送一个网络请求。在 *二进制插件* 模型里,Kubernetes 执行一个二进制(程序)。二进制插件被 kubelet(如 [Flex 卷插件](https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md)和[网络插件](/docs/concepts/cluster-administration/network-plugins/))和 kubectl 所使用。 + +下图显示了扩展点如何与 Kubernetes 控制平面进行交互。 + + + + + + +## 扩展点 + +下图显示了 Kubernetes 系统的扩展点。 + + + + + + +1. 用户通常使用 `kubectl` 与 Kubernetes API 进行交互。[kubectl 插件](/docs/tasks/extend-kubectl/kubectl-plugins/)扩展了 kubectl 二进制程序。它们只影响个人用户的本地环境,因此不能执行站点范围的策略。 +2. apiserver 处理所有请求。apiserver 中的几种类型的扩展点允许对请求进行身份认证或根据其内容对其进行阻止、编辑内容以及处理删除操作。这些内容在[API 访问扩展](/docs/concepts/overview/extending#api-access-extensions)小节中描述。 +3. apiserver 提供各种 *资源* 。 *内置的资源种类* ,如 `pods`,由 Kubernetes 项目定义,不能更改。您还可以添加您自己定义的资源或其他项目已定义的资源,称为 自定义资源,如[自定义资源](/docs/concepts/overview/extending#user-defined-types)部分所述。自定义资源通常与 API 访问扩展一起使用。 +4. Kubernetes 调度器决定将 Pod 放置到哪个节点。有几种方法可以扩展调度器。这些内容在 [Scheduler Extensions](/docs/concepts/overview/extending#scheduler-extensions) 小节中描述。 +5. Kubernetes 的大部分行为都是由称为控制器的程序实现的,这些程序是 API-Server 的客户端。控制器通常与自定义资源一起使用。 +6. kubelet 在主机上运行,并帮助 pod 看起来就像在集群网络上拥有自己的 IP 的虚拟服务器。[网络插件](/docs/concepts/overview/extending#network-plugins)让您可以实现不同的 pod 网络。 +7. kubelet 也挂载和卸载容器的卷。新的存储类型可以通过[存储插件](/docs/concepts/overview/extending#storage-plugins)支持。 + +如果您不确定从哪里开始扩展,此流程图可以提供帮助。请注意,某些解决方案可能涉及多种类型的扩展。 + + + + + + +## API 扩展 +### 用户自定义类型 + +如果您想定义新的控制器、应用程序配置对象或其他声明式 API,并使用 Kubernetes 工具(如 `kubectl`)管理它们,请考虑为 Kubernetes 添加一个自定义资源。 + +不要使用自定义资源作为应用、用户或者监控数据的数据存储。 + +有关自定义资源的更多信息,请查看[自定义资源概念指南](/docs/concepts/api-extension/custom-resources/)。 + + +### 将新的 API 与自动化相结合 + +通常,在您添加新的 API 时,还需要添加一个读取和(或)写入新 API 的循环控制线程。当使用自定义 API 和循环控制线程的组合来管理特定的(通常是有状态的)应用程序时,这称为 *Operator* 模式。自定义 API 和循环控制线程也可以用来控制其他资源,例如存储、策略等等。 + + +### 改变内置资源 + +当您通过添加自定义资源来扩展 Kubernetes API 时,添加的资源始终属于新的 API 组。您不能替换或更改已有的 API 组。添加 API 不会直接影响现有 API(例如 Pod )的行为,但是 API 访问扩展可以。 + + +### API 访问扩展 + +当请求到达 Kubernetes API Server 时,它首先被要求进行用户认证,然后要进行授权检查,接着受到各种类型的准入控制的检查。有关此流程的更多信息,请参阅 [Kubernetes API访问控制](/docs/reference/access-authn-authz/controlling-access/)。 + +上述每个步骤都提供了扩展点。 + +Kubernetes 有几个它支持的内置认证方法。它还可以位于身份验证代理之后,并将授权 header 中的令牌发送给远程服务进行验证(webhook)。所有这些方法都在[身份验证文档](/docs/reference/access-authn-authz/authentication/)中介绍。 + + +### 身份认证 + +[身份认证](/docs/reference/access-authn-authz/authentication/)将所有请求中的 header 或证书映射为发出请求的客户端的用户名。 + +Kubernetes 提供了几种内置的身份认证方法,如果这些方法不符合您的需求,可以使用[身份认证 webhook](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) 方法。 + + +### 授权 + +[授权](/docs/reference/access-authn-authz/webhook/)决定特定用户是否可以对 API 资源执行读取、写入以及其他操作。它只是在整个资源的层面上工作 -- 它不基于任意的对象字段进行区分。如果内置授权选项不能满足您的需求,[授权 webhook](/docs/reference/access-authn-authz/webhook/) 允许调用用户提供的代码来作出授权决定。 + + +### 动态准入控制 + +在请求被授权之后,如果是写入操作,它还将进入[准入控制](/docs/reference/access-authn-authz/admission-controllers/)步骤。除了内置的步骤之外,还有几个扩展: + +* [镜像策略 webhook](/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook) 限制了哪些镜像可以在容器中运行。 +* 为了进行灵活的准入控制决策,可以使用通用的 [Admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)。Admission Webhooks 可以拒绝创建或更新操作。 + + +## 基础设施扩展 + + +### 存储插件 + +[Flex Volumes](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/flexvolume-deployment.md +) 允许用户挂载无内置插件支持的卷类型,它通过 Kubelet 调用一个二进制插件来挂载卷。 + + +### 设备插件 + +设备插件允许节点通过[设备插件](/docs/concepts/cluster-administration/device-plugins/)发现新的节点资源(除了内置的 CPU 和内存之外)。 + + +### 网络插件 + +不同的网络结构可以通过节点级的[网络插件](/docs/admin/network-plugins/)支持。 + + +### 调度器扩展 + +调度器是一种特殊类型的控制器,用于监视 pod 并将其分配到节点。默认的调度器可以完全被替换,而继续使用其他 Kubernetes 组件,或者可以同时运行[多个调度器](/docs/tasks/administer-cluster/configure-multiple-schedulers/)。 + +这是一个重要的任务,几乎所有的 Kubernetes 用户都发现他们不需要修改调度器。 + +调度器也支持 [webhook](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md),它允许一个 webhook 后端(调度器扩展程序)为 pod 筛选节点和确定节点的优先级。 + +{{% /capture %}} + + +{{% capture whatsnext %}} + + +* 详细了解[自定义资源](/docs/concepts/api-extension/custom-resources/) +* 了解[动态准入控制](/docs/reference/access-authn-authz/extensible-admission-controllers/) +* 详细了解基础设施扩展 + * [网络插件](/docs/concepts/cluster-administration/network-plugins/) + * [设备插件](/docs/concepts/cluster-administration/device-plugins/) +* 了解 [kubectl 插件](/docs/tasks/extend-kubectl/kubectl-plugins/) +* 查看自动化的例子 + * [Operator 列表](https://github.com/operator-framework/awesome-operators) + +{{% /capture %}} diff --git a/content/zh/docs/concepts/extend-kubernetes/service-catalog.md b/content/zh/docs/concepts/extend-kubernetes/service-catalog.md new file mode 100644 index 0000000000000..ab8494e637854 --- /dev/null +++ b/content/zh/docs/concepts/extend-kubernetes/service-catalog.md @@ -0,0 +1,457 @@ +--- +title: 服务目录 +reviewers: +- chenopis +content_template: templates/concept +weight: 40 +--- + + +{{% capture overview %}} +{{< glossary_definition term_id="service-catalog" length="all" prepend="" >}} + + +服务代理是由[开放服务代理 API 规范](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md)定义的一组托管服务的终结点,由第三方提供并维护,其中的第三方可以是 AWS,GCP 或 Azure 等云服务提供商。 +托管服务的一些示例是 Microsoft Azure Cloud Queue,Amazon Simple Queue Service 和 Google Cloud Pub/Sub,但它们是可以使用应用程序的任何软件产品。 + +使用服务目录,集群操作者可以浏览其提供的托管服务列表,提供托管服务实例并与之绑定,以使其可以被 Kubernetes 集群中的应用程序使用。 + +{{% /capture %}} + + +{{% capture body %}} + +## 示例用例 + +应用开发者希望使用消息队列作为其在 Kubernetes 集群中运行的应用程序的一部分。 +但是,它们不想承受建立这种服务的开销,也不想自行管理。幸运的是,有一家云服务提供商通过它们的服务代理将消息队列作为托管服务提供。 + +集群运维人员可以设置服务目录并使用它与云服务提供商的服务代理 通信,以此提供消息队列服务的实例并使其对 Kubernetes 中的应用程序可用。 +因此,应用开发者可以不用关心消息队列的实现细节,也不用对其进行管理。它们的应用程序可以简单的将其作为服务使用。 + + +## 架构 +服务目录使用[开放服务代理 API](https://github.com/openservicebrokerapi/servicebroker) 与服务代理进行通信,并作为 Kubernetes API Server 的中介,以便协商首要规定并获取应用程序使用托管服务的必要凭据。 + +它被实现为一个扩展 API 服务和一个控制器管理器,使用 Etcd 作为存储。它还使用了 Kubernetes 1.7+ 版本中提供的 [aggregation layer](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) 来呈现其 API。 + +
+ +![Service Catalog Architecture](/images/docs/service-catalog-architecture.svg) + + +## API 资源 + +服务目录安装 `servicecatalog.k8s.io` API 并提供以下 Kubernetes 资源: + +* `ClusterServiceBroker`:服务目录的集群内代表,封装了它的服务连接细节。集群运维人员创建和管理这些资源,并希望使用该代理服务在集群中提供新类型的托管服务。 +* `ClusterServiceClass`:由特定服务代理提供的托管服务。当新的 `ClusterServiceBroker` 资源被添加到集群时,服务目录控制器将连接到服务代理以获取可用的托管服务列表。然后为每个托管服务创建对应的新 `ClusterServiceClass` 资源。 +* `ClusterServicePlan`:托管服务的特定产品。例如托管服务可能有不同的计划可用,如免费版本和付费版本,或者可能有不同的配置选项,例如使用 SSD 存储或拥有更多资源。与 `ClusterServiceClass` 类似,当一个新的 `ClusterServiceBroker` 被添加到集群时,服务目录会为每个托管服务的每个可用服务计划创建对应的新 `ClusterServicePlan` 资源。 +* `ServiceInstance`:`ClusterServiceClass` 提供的示例。由集群运维人员创建,以使托管服务的特定实例可供一个或多个集群内应用程序使用。当创建一个新的 `ServiceInstance` 资源时,服务目录控制器将连接到相应的服务代理并指示它调配服务实例。 +* `ServiceBinding`:`ServiceInstance` 的访问凭据。由希望其应用程序使用服务 `ServiceInstance` 的集群运维人员创建。创建之后,服务目录控制器将创建一个 Kubernetes `Secret`,其中包含服务实例的连接细节和凭据,可以挂载到 Pod 中。 + + +### 认证 + +服务目录支持这些认证方法: + +* 基础认证(用户名/密码) +* [OAuth 2.0 不记名令牌](https://tools.ietf.org/html/rfc6750) + + +## 使用方式 + +集群运维人员可以使用服务目录 API 资源来提供托管服务并使其在 Kubernetes 集群内可用。涉及的步骤有: + +1. 列出服务代理提供的托管服务和服务计划。 +2. 配置托管服务的新实例。 +3. 绑定到托管服务,它将返回连接凭证。 +4. 将连接凭证映射到应用程序中。 + + +### 列出托管服务和服务计划 + +首先,集群运维人员在 `servicecatalog.k8s.io` 组内创建一个 `ClusterServiceBroker` 资源。此资源包含访问服务代理终结点所需的 URL 和连接详细信息。 + +这是一个 `ClusterServiceBroker` 资源的例子: + +```yaml +apiVersion: servicecatalog.k8s.io/v1beta1 +kind: ClusterServiceBroker +metadata: + name: cloud-broker +spec: + # Points to the endpoint of a service broker. (This example is not a working URL.) + url: https://servicebroker.somecloudprovider.com/v1alpha1/projects/service-catalog/brokers/default + ##### + # Additional values can be added here, which may be used to communicate + # with the service broker, such as bearer token info or a caBundle for TLS. + ##### +``` + +下面的顺序图展示了从一个服务代理列出可用托管服务和计划所有涉及的步骤: + +![List Services](/images/docs/service-catalog-list.svg) + +1. 一旦 `ClusterServiceBroker` 资源被添加到了服务目录之后,将会触发一个到外部服务代理的 List Services 调用。 +1. 服务代理返回可用的托管服务和服务计划列表,这些列表将本地缓存在 `ClusterServiceClass` 和 `ClusterServicePlan` 资源中。 +1. 然后集群运维人员可以使用以下命令获取可用托管服务的列表: + + kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName + + 它应该输出一个和以下格式类似的服务名称列表: + + SERVICE NAME EXTERNAL NAME + 4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 cloud-provider-service + ... ... + + 他们还可以使用以下命令查看可用的服务计划: + + kubectl get clusterserviceplans -o=custom-columns=PLAN\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName + + 它应该输出一个和以下格式类似的服务计划列表: + + PLAN NAME EXTERNAL NAME + 86064792-7ea2-467b-af93-ac9694d96d52 service-plan-name + ... ... + + +### 配置一个新实例 + +集群运维人员 可以通过创建一个 `ServiceInstance` 资源来启动一个新实例的配置。 + +这是一个 `ServiceInstance` 资源的例子: + +```yaml +apiVersion: servicecatalog.k8s.io/v1beta1 +kind: ServiceInstance +metadata: + name: cloud-queue-instance + namespace: cloud-apps +spec: + # References one of the previously returned services + clusterServiceClassExternalName: cloud-provider-service + clusterServicePlanExternalName: service-plan-name + ##### + # Additional parameters can be added here, + # which may be used by the service broker. + ##### +``` + +以下顺序图展示了配置托管服务新实例所涉及的步骤: + +![Provision a Service](/images/docs/service-catalog-provision.svg) + +1. 当创建 `ServiceInstance` 资源时,服务目录将启动一个到外部服务代理的配置实例调用。 +1. 服务代理创建一个托管服务的新实例并返回 HTTP 响应。 +1. 然后集群运维人员可以检查实例的状态是否就绪。 + + +### 绑定到托管服务 + +在设置新实例之后,集群运维人员必须绑定到托管服务才能获取应用程序使用服务所需的连接凭据和服务账户的详细信息。该操作通过创建一个 `ServiceBinding` 资源完成。 + +以下是 `ServiceBinding` 资源的示例: + +```yaml +apiVersion: servicecatalog.k8s.io/v1beta1 +kind: ServiceBinding +metadata: + name: cloud-queue-binding + namespace: cloud-apps +spec: + instanceRef: + name: cloud-queue-instance + ##### + # Additional information can be added here, such as a secretName or + # service account parameters, which may be used by the service broker. + ##### +``` + +以下顺序图展示了绑定到托管服务实例的步骤: + +![Bind to a managed service](/images/docs/service-catalog-bind.svg) + +1. 在创建 `ServiceBinding` 之后,服务目录调用外部服务代理,请求绑定服务实例所需的信息。 +1. 服务代理为相应服务账户启用应用权限/角色。 +1. 服务代理返回连接和访问托管服务示例所需的信息。这是由提供商和服务特定的,故返回的信息可能因服务提供商和其托管服务而有所不同。 + + +### 映射连接凭据 + +完成绑定之后的最后一步就是将连接凭据和服务特定的信息映射到应用程序中。这些信息存储在 secret 中,集群中的应用程序可以访问并使用它们直接与托管服务进行连接。 + +
+ +![Map connection credentials](/images/docs/service-catalog-map.svg) + + +#### Pod 配置文件 + +执行此映射的一种方法是使用声明式 Pod 配置。 + +以下示例描述了如何将服务账户凭据映射到应用程序中。名为 `sa-key` 的密钥保存在一个名为 `provider-cloud-key` 的卷中,应用程序会将该卷挂载在 `/var/secrets/provider/key.json` 路径下。环境变量 `PROVIDER_APPLICATION_CREDENTIALS` 将映射为挂载文件的路径。 + +```yaml +... + spec: + volumes: + - name: provider-cloud-key + secret: + secretName: sa-key + containers: +... + volumeMounts: + - name: provider-cloud-key + mountPath: /var/secrets/provider + env: + - name: PROVIDER_APPLICATION_CREDENTIALS + value: "/var/secrets/provider/key.json" +``` + +以下示例描述了如何将 secret 值映射为应用程序的环境变量。在这个示例中,消息队列的主题名从 secret `provider-queue-credentials` 中名为 `topic` 的 key 项映射到环境变量 `TOPIC` 中。 + + +```yaml +... + env: + - name: "TOPIC" + valueFrom: + secretKeyRef: + name: provider-queue-credentials + key: topic +``` + +{{% /capture %}} + + +{{% capture whatsnext %}} + +* 如果您熟悉{{< glossary_tooltip text="Helm Charts" term_id="helm-chart" >}},您可以[使用 Helm 将服务目录](/docs/tasks/service-catalog/install-service-catalog-using-helm/)安装到 Kubernetes 集群中。或者,您可以[使用 SC 工具安装服务目录](/docs/tasks/service-catalog/install-service-catalog-using-sc/)。 +* 查看[服务代理示例](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers)。 +* 浏览 [kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog) 项目。 +* 查看 [svc-cat.io](https://svc-cat.io/docs/)。 +{{% /capture %}} + + + diff --git a/content/zh/docs/concepts/overview/_index.md b/content/zh/docs/concepts/overview/_index.md index 9ab3e94ae4062..87550923ffca5 100755 --- a/content/zh/docs/concepts/overview/_index.md +++ b/content/zh/docs/concepts/overview/_index.md @@ -1,4 +1,11 @@ --- -title: "概述" +title: 概述 weight: 20 ---- \ No newline at end of file +--- + + diff --git a/content/zh/docs/concepts/overview/components.md b/content/zh/docs/concepts/overview/components.md index 124f5a2d780fa..f0b373bb12951 100644 --- a/content/zh/docs/concepts/overview/components.md +++ b/content/zh/docs/concepts/overview/components.md @@ -22,7 +22,7 @@ Master 组件可以在集群中的任何节点上运行。然而,为了简单 ### API服务器 -[kube-apiserver](/docs/admin/kube-apiserver)对外暴露了Kubernetes API。它是的 Kubernetes 前端控制层。它被设计为水平扩展,即通过部署更多实例来缩放。请参阅[构建高可用性群集](/docs/admin/high-availability). +[kube-apiserver](/docs/admin/kube-apiserver)对外暴露了Kubernetes API。它是 Kubernetes 的前端控制层。它被设计为水平扩展,即通过部署更多实例来缩放。请参阅[构建高可用性群集](/docs/admin/high-availability). ### etcd diff --git a/content/zh/docs/concepts/overview/kubernetes-api.md b/content/zh/docs/concepts/overview/kubernetes-api.md index 9a920f043fbac..5364b81a82d77 100644 --- a/content/zh/docs/concepts/overview/kubernetes-api.md +++ b/content/zh/docs/concepts/overview/kubernetes-api.md @@ -7,11 +7,11 @@ weight: 30 [API协议文档](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md)描述了主系统和API概念。 -[API参考文档](https://kubernetes.io/docs/reference)描述了API整体规范。 +[API参考文档](/docs/reference)描述了API整体规范。 -[访问文档](https://kubernetes.io/docs/admin/accessing-the-api)讨论了通过远程访问API的相关问题。 +[访问文档](/docs/admin/accessing-the-api)讨论了通过远程访问API的相关问题。 -Kubernetes API是系统描述性配置的基础。 [Kubectl](https://kubernetes.io/docs/user-guide/kubectl/) 命令行工具被用于创建、更新、删除、获取API对象。 +Kubernetes API是系统描述性配置的基础。 [Kubectl](/docs/user-guide/kubectl/) 命令行工具被用于创建、更新、删除、获取API对象。 Kubernetes 通过API资源存储自己序列化状态(现在存储在[etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/))。 @@ -82,11 +82,11 @@ Kubernetes实现了另一种基于Protobuf的序列化格式,该格式主要 1. 核心组(通常被称为遗留组)位于REST路径 **`/api/v1`** 并使用 **`apiVersion:v1`**。 -1. 指定的组位于REST路径 **`/apis/$GROUP_NAME/$VERSION`**,并使用 **`apiVersion:$GROUP_NAME/$VERSION`**(例如 **`apiVersion:batch/v1`**)。 在[Kubernetes API参考](https://kubernetes.io/docs/reference/)中可以看到支持的API组的完整列表。 +1. 指定的组位于REST路径 **`/apis/$GROUP_NAME/$VERSION`**,并使用 **`apiVersion:$GROUP_NAME/$VERSION`**(例如 **`apiVersion:batch/v1`**)。 在[Kubernetes API参考](/docs/reference/)中可以看到支持的API组的完整列表。 -社区支持使用以下两种方式来提供自定义资源对API进行扩展[自定义资源](https://kubernetes.io/docs/concepts/api-extension/custom-resources/): +社区支持使用以下两种方式来提供自定义资源对API进行扩展[自定义资源](/docs/concepts/api-extension/custom-resources/): -1. [CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)适用于具有非常基本的CRUD需求的用户。 +1. [CustomResourceDefinition](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)适用于具有非常基本的CRUD需求的用户。 1. 即将推出:需要全套Kubernetes API语义的用户可以实现自己的apiserver,并使用[聚合器](https://git.k8s.io/community/contributors/design-proposals/api-machinery/aggregated-api-servers.md)为客户提供无缝的服务。 diff --git a/content/zh/docs/concepts/overview/object-management-kubectl/_index.md b/content/zh/docs/concepts/overview/object-management-kubectl/_index.md new file mode 100644 index 0000000000000..3ee775f5a6d78 --- /dev/null +++ b/content/zh/docs/concepts/overview/object-management-kubectl/_index.md @@ -0,0 +1,11 @@ +--- +title: "用 kubectl 管理对象" +weight: 50 +--- + + diff --git a/content/zh/docs/concepts/overview/object-management-kubectl/imperative-config.md b/content/zh/docs/concepts/overview/object-management-kubectl/imperative-config.md new file mode 100644 index 0000000000000..ac923edef9917 --- /dev/null +++ b/content/zh/docs/concepts/overview/object-management-kubectl/imperative-config.md @@ -0,0 +1,262 @@ +--- +title: 使用配置文件指令式管理 Kubernetes 对象 +content_template: templates/concept +weight: 30 +--- + + + +{{% capture overview %}} + +通过使用 `kubectl` 命令行工具和 yaml 或 json 格式编写的对象配置文件,用户可以创建、更新和删除 Kubernetes 对象。 +本文档介绍如何使用配置文件定义和管理对象。 +{{% /capture %}} + +{{% capture body %}} + + +## 取舍权衡 + + + +`kubectl` 工具支持三种对象管理: + + +* 指令性命令 +* 指令性对象配置 +* 声明式对象配置 + + +请参阅[Kubernetes 对象管理](/docs/concepts/overview/object-management-kubectl/overview/) 以了解每种对象管理的优缺点。 + + +## 怎样创建对象 + + + +可以使用 `kubectl create -f` 从配置文件创建对象。 +有关详细信息,请参阅[Kubernetes API 参考](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)。 + +- `kubectl create -f ` + + +## 怎样更新对象 + +{{< warning >}} + +使用 `replace` 命令更新对象时,系统将会删除配置文件的 spec 中未指定的所有内容。 +对于部分上由集群来管理的对象而言,不要使用这种对象管理方式。 + +例如,对于 `LoadBalancer` 类型的服务而言,其 `externalIPs` 字段值是独立于配置文件进行管理的。 +独立管理的字段必须复制到配置文件中,以防止被 `replace` 操作删除。 +{{< /warning >}} + + +您可以使用 `kubectl replace -f` 命令基于配置文件来更新活跃状态的对象。 + +- `kubectl replace -f ` + + +## 怎样删除对象 + + + +您可以使用 `kubectl delete -f` 命令来删除配置文件中描述的对象。 + +- `kubectl delete -f ` + + +## 怎样查看对象 + + + +您可以使用 `kubectl get -f` 命令来查看配置文件中描述的对象的信息。 + +- `kubectl get -f -o yaml` + + + +指定了 `-o yaml` 参数将会打印完整的对象配置。 +使用 `kubectl get -h` 命令查看选项列表。 + + +## 限制 + + +当每个对象的配置都完整的定义和记录在它的配置文件中时,`create`、`replace` 和 `delete` 命令就能正常使用。 +然而,当一个存活态的对象被更新、并且更新的内容没有被合入该对象的配置文件时,下次再执行 `replace` 命令将导致更新的内容丢失。 +如果控制器(如 HorizontalPodAutoscaler)直接更新存活态的对象,就会发生上面的情况。 +下面是个例子: + + + +1. 从配置文件创建对象。 +1. 另外一个资源更新这个对象的一些字段。 +1. 从配置文件中替换(replace)该对象。第二步中另外的资源对该对象所做的更新将丢失。 + + +如果您需要对同一对象支持多个写者,那么可以使用 `kubectl apply` 命令管理该对象。 + + +## 通过 URL 创建和编辑对象而不保存配置 + + + +假设您知道一个对象配置文件的 URL。 +您可以在对象被创建之前使用 `kubectl create --edit` 命令来更改它的配置。 +这对于指向那些读者可修改配置文件的教程和任务特别有用。 + +```sh +kubectl create -f --edit +``` + + +## 从指令性命令迁移到指令性对象配置 + + +从指令性命令迁移到指令性对象配置包括几个手动步骤。 + + +1. 将存活态的对象导出为本地对象配置文件: +```sh +kubectl get / -o yaml --export > _.yaml +``` +1. 手动从对象配置文件中移除状态信息。 +1. 对于后续的对象管理,只使用 `replace`。 +```sh +kubectl replace -f _.yaml +``` + + +## 定义控制器选择器和 PodTemplate 标签 + +{{< warning >}} + +强烈不建议更新控制器的选择器。 +{{< /warning >}} + + +建议的方法是定义一个单一的、不变的 PodTemplate 标签,该标签仅由控制器选择器使用,没有其他语义意义。 + + +标签示例: + +```yaml +selector: + matchLabels: + controller-selector: "extensions/v1beta1/deployment/nginx" +template: + metadata: + labels: + controller-selector: "extensions/v1beta1/deployment/nginx" +``` + +{{% /capture %}} + +{{% capture whatsnext %}} + + +- [使用指令性命令管理 Kubernetes 对象](/docs/concepts/overview/object-management-kubectl/imperative-command/) +- [使用对象配置文件(声明式)管理 Kubernetes 对象](/docs/concepts/overview/object-management-kubectl/declarative-config/) +- [Kubectl 命令参考](/docs/reference/generated/kubectl/kubectl/) +- [Kubernetes API 参考](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) +{{% /capture %}} + + diff --git a/content/zh/docs/concepts/overview/working-with-objects/_index.md b/content/zh/docs/concepts/overview/working-with-objects/_index.md index 5dcf6e4ed5620..477bdc5b18829 100755 --- a/content/zh/docs/concepts/overview/working-with-objects/_index.md +++ b/content/zh/docs/concepts/overview/working-with-objects/_index.md @@ -1,4 +1,11 @@ --- title: "使用 Kubernetes 对象" weight: 40 ---- \ No newline at end of file +--- + + diff --git a/content/zh/docs/concepts/overview/working-with-objects/annotations.md b/content/zh/docs/concepts/overview/working-with-objects/annotations.md new file mode 100644 index 0000000000000..91bd7064e19d1 --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/annotations.md @@ -0,0 +1,129 @@ +--- +title: 注解 +content_template: templates/concept +weight: 50 +--- + + + +{{% capture overview %}} + +你可以使用 Kubernetes 注解为对象附加任意的非标识的元数据。客户端程序(例如工具和库)能够获取这些元数据信息。 + +{{% /capture %}} + +{{% capture body %}} +## 为对象附加元数据 + + +您可以使用标签或注解将元数据附加到 Kubernetes 对象。标签可以用来选择对象和查找满足某些条件的对象集合。 + + +相反,注解不用于标识和选择对象。 +注解中的元数据,可以很小,也可以很大,可以是结构化的,也可以是非结构化的,能够包含标签不允许的字符。 + + +注解和标签一样,是键/值对: + + +```json +"metadata": { + "annotations": { + "key1" : "value1", + "key2" : "value2" + } +} +``` + +以下是一些例子,用来说明哪些信息可以使用注解来记录: + + +* 由声明性配置所管理的字段。 + 将这些字段附加为注解,能够将它们与客户端或服务端设置的默认值、自动生成的字段以及通过自动调整大小或自动伸缩系统设置的字段区分开来。 + + + +* 构建、发布或镜像信息(如时间戳、发布 ID、Git 分支、PR 数量、镜像哈希、仓库地址)。 + + + +* 指向日志记录、监控、分析或审计仓库的指针。 + + + +* 可用于调试目的的客户端库或工具信息:例如,名称、版本和构建信息。 + + + +* 用户或者工具/系统的来源信息,例如来自其他生态系统组件的相关对象的 URL。 + + + +* 推出的轻量级工具的元数据信息:例如,配置或检查点。 + + + +* 负责人员的电话或呼机号码,或指定在何处可以找到该信息的目录条目,如团队网站。 + + + +您可以将这类信息存储在外部数据库或目录中而不使用注解,但这样做就使得开发人员很难生成用于部署、管理、自检的客户端共享库和工具。 + + +{{% /capture %}} + +{{% capture whatsnext %}} +进一步了解[标签和选择器](/docs/concepts/overview/working-with-objects/labels/)。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/overview/working-with-objects/common-labels.md b/content/zh/docs/concepts/overview/working-with-objects/common-labels.md new file mode 100644 index 0000000000000..f1b3575c4502d --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/common-labels.md @@ -0,0 +1,259 @@ +--- +title: 推荐使用的标签 +content_template: templates/concept +--- + + +{{% capture overview %}} + +除了 kubectl 和 dashboard 之外,您可以其他工具来可视化和管理 Kubernetes 对象。 +一组通用的标签可以让多个工具之间互操作,用所有工具都能理解的通用方式描述对象。 + + +除了支持工具外,推荐的标签还以一种可以查询的方式描述了应用程序。 + +{{% /capture %}} + +{{% capture body %}} + +元数据围绕 _应用(application)_ 的概念进行组织。Kubernetes 不是 +平台即服务(PaaS),没有或强制执行正式的应用程序概念。 +相反,应用程序是非正式的,并使用元数据进行描述。应用程序包含的定义是松散的。 + +{{< note >}} + +这些是推荐的标签。它们使管理应用程序变得更容易但不是任何核心工具所必需的。 +{{< /note >}} + + +共享标签和注解都使用同一个前缀:`app.kubernetes.io`。没有前缀的标签是用户私有的。共享前缀可以确保共享标签不会干扰用户自定义的标签。 + + +## 标签 +为了充分利用这些标签,应该在每个资源对象上都使用它们。 + + +| 键 | 描述 | 示例 | 类型 | +| ----------------------------------- | --------------------- | -------- | ---- | +| `app.kubernetes.io/name` | 应用程序的名称 | `mysql` | 字符串 | +| `app.kubernetes.io/instance` | 用于唯一确定应用实例的名称 | `wordpress-abcxzy` | 字符串 | +| `app.kubernetes.io/version` | 应用程序的当前版本(例如,语义版本,修订版哈希等) | `5.7.21` | 字符串 | +| `app.kubernetes.io/component` | 架构中的组件 | `database` | 字符串 | +| `app.kubernetes.io/part-of` | 此级别的更高级别应用程序的名称 | `wordpress` | 字符串 | +| `app.kubernetes.io/managed-by` | 用于管理应用程序的工具 | `helm` | 字符串 | + +为说明这些标签的实际使用情况,请看下面的 StatefulSet 对象: + +```yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/name: mysql + app.kubernetes.io/instance: wordpress-abcxzy + app.kubernetes.io/version: "5.7.21" + app.kubernetes.io/component: database + app.kubernetes.io/part-of: wordpress + app.kubernetes.io/managed-by: helm +``` + + +## 应用和应用实例 + +应用可以在 Kubernetes 集群中安装一次或多次。在某些情况下,可以安装在同一命名空间中。例如,可以不止一次地为不同的站点安装不同的 wordpress。 + +应用的名称和实例的名称是分别记录的。例如,某 WordPress 实例的 `app.kubernetes.io/name` 为 `wordpress`,而其实例名称表现为 `app.kubernetes.io/instance` 的属性值 `wordpress-abcxzy`。这使应用程序和应用程序的实例成为可能是可识别的。应用程序的每个实例都必须具有唯一的名称。 + + +## 示例 + + +为了说明使用这些标签的不同方式,以下示例具有不同的复杂性。 + + +### 一个简单的无状态服务 + + +考虑使用 `Deployment` 和 `Service` 对象部署的简单无状态服务的情况。以下两个代码段表示如何以最简单的形式使用标签。 + + +下面的 `Deployment` 用于监督运行应用本身的 pods。 +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: myservice + app.kubernetes.io/instance: myservice-abcxzy +... +``` + + +下面的 `Service` 用于暴露应用。 +```yaml +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: myservice + app.kubernetes.io/instance: myservice-abcxzy +... +``` + + +### 带有一个数据库的 Web 应用程序 + + +考虑一个稍微复杂的应用:一个使用 Helm 安装的 Web 应用(WordPress),其中 +使用了数据库(MySQL)。以下代码片段说明用于部署此应用程序的对象的开始。 + +以下 `Deployment` 的开头用于 WordPress: + + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: wordpress + app.kubernetes.io/instance: wordpress-abcxzy + app.kubernetes.io/version: "4.9.4" + app.kubernetes.io/managed-by: helm + app.kubernetes.io/component: server + app.kubernetes.io/part-of: wordpress +... +``` + + +这个 `Service` 用于暴露 WordPress: + +```yaml +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: wordpress + app.kubernetes.io/instance: wordpress-abcxzy + app.kubernetes.io/version: "4.9.4" + app.kubernetes.io/managed-by: helm + app.kubernetes.io/component: server + app.kubernetes.io/part-of: wordpress +... +``` + + +MySQL 作为一个 `StatefulSet` 暴露,包含它和它所属的较大应用程序的元数据: +```yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/name: mysql + app.kubernetes.io/instance: wordpress-abcxzy + app.kubernetes.io/managed-by: helm + app.kubernetes.io/component: database + app.kubernetes.io/part-of: wordpress + app.kubernetes.io/version: "5.7.21" +... +``` + + +`Service` 用于将 MySQL 作为 WordPress 的一部分暴露: +```yaml +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: mysql + app.kubernetes.io/instance: wordpress-abcxzy + app.kubernetes.io/managed-by: helm + app.kubernetes.io/component: database + app.kubernetes.io/part-of: wordpress + app.kubernetes.io/version: "5.7.21" +... +``` + + +使用 MySQL `StatefulSet` 和 `Service`,您会注意到有关 MySQL 和 Wordpress 的信息,包括更广泛的应用程序。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/overview/working-with-objects/field-selectors.md b/content/zh/docs/concepts/overview/working-with-objects/field-selectors.md new file mode 100644 index 0000000000000..b00442633c777 --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/field-selectors.md @@ -0,0 +1,106 @@ +--- +title: 字段选择器 +weight: 60 +--- + + + +字段选择器允许您根据一个或多个资源字段的值[筛选 Kubernetes 资源](/docs/concepts/overview/working-with-objects/kubernetes-objects)。 +下面是一些使用字段选择器查询的例子: + + +* `metadata.name=my-service` +* `metadata.namespace!=default` +* `status.phase=Pending` + +下面这个 `kubectl` 命令将筛选出[`status.phase`](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)字段值为 `Running` 的所有 Pod: + + +```shell +$ kubectl get pods --field-selector status.phase=Running +``` + +{{< note >}} + +字段选择器本质上是资源*过滤器*。默认情况下,字段选择器/过滤器是未被应用的,这意味着指定类型的所有资源都会被筛选出来。 +这使得以下的两个 `kubectl` 查询是等价的: + + +```shell +$ kubectl get pods +$ kubectl get pods --field-selector "" +``` +{{< /note >}} + +## 支持的字段 + + +不同的 Kubernetes 资源类型支持不同的字段选择器。 +所有资源类型都支持 `metadata.name` 和 `metadata.namespace` 字段。 +使用不被支持的字段选择器会产生错误,例如: + + +```shell +$ kubectl get ingress --field-selector foo.bar=baz +Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace" +``` + +## 支持的运算符 + + +您可以使用 `=`、`==`和 `!=` 对字段选择器进行运算(`=` 和 `==` 的意义是相同的)。 +例如,下面这个 `kubectl` 命令将筛选所有不属于 `default` 名称空间的 Kubernetes Service: + + +```shell +$ kubectl get services --field-selector metadata.namespace!=default +``` + +## 链式选择器 + + +同[标签](/docs/concepts/overview/working-with-objects/labels)和其他选择器一样,字段选择器可以通过使用逗号分隔的列表组成一个选择链。 +下面这个 `kubectl` 命令将筛选 `status.phase` 字段不等于 `Running` 同时 `spec.restartPolicy` 字段等于 `Always` 的所有 Pod: + + +```shell +$ kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always +``` + +## 多种资源类型 + + +您能够跨多种资源类型来使用字段选择器。 +下面这个 `kubectl` 命令将筛选出所有不在 `default` 命名空间中的 StatefulSet 和 Service: + + +```shell +$ kubectl get statefulsets,services --field-selector metadata.namespace!=default +``` diff --git a/content/zh/docs/concepts/overview/working-with-objects/labels.md b/content/zh/docs/concepts/overview/working-with-objects/labels.md new file mode 100644 index 0000000000000..3bc5554c5e679 --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/labels.md @@ -0,0 +1,378 @@ +--- +title: 标签和选择器 +content_template: templates/concept +weight: 40 +--- + +{{% capture overview %}} + + +_标签_ 是附加到 Kubernetes 对象(比如 Pods)上的键值对。 +标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 +标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 +每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。 + +```json +"metadata": { + "labels": { + "key1" : "value1", + "key2" : "value2" + } +} +``` + + + +我们最终将标签索引和反向索引,用于高效查询和监视,使用它们在 UI 和 CLI 中进行排序和分组等。我们不希望将非标识性的、尤其是大型或结构化数据用作标签,给后者带来污染。应使用 [注解](/docs/concepts/overview/working-with-objects/annotations/) 记录非识别信息 + +{{% /capture %}} + + +{{% capture body %}} + + + +## 动机 + + +标签使用户能够以松散耦合的方式将他们自己的组织结构映射到系统对象,而无需客户端存储这些映射。 + + +服务部署和批处理流水线通常是多维实体(例如,多个分区或部署、多个发行序列、多个层,每层多个微服务)。管理通常需要交叉操作,这打破了严格的层次表示的封装,特别是由基础设施而不是用户确定的严格的层次结构。 + + +示例标签: + + * `"release" : "stable"`, `"release" : "canary"` + * `"environment" : "dev"`, `"environment" : "qa"`, `"environment" : "production"` + * `"tier" : "frontend"`, `"tier" : "backend"`, `"tier" : "cache"` + * `"partition" : "customerA"`, `"partition" : "customerB"` + * `"track" : "daily"`, `"track" : "weekly"` + + +这些只是常用标签的例子; 您可以任意制定自己的约定。请记住,对于给定对象标签的键必须是唯一的。 + + +## 语法和字符集 + + + +_标签_ 是键值对。有效的标签键有两个段:可选的前缀和名称,用斜杠(`/`)分隔。名称段是必需的,必须小于等于 63 个字符,以字母数字字符(`[a-z0-9A-Z]`)开头和结尾,带有破折号(`-`),下划线(`_`),点( `.`)和之间的字母数字。前缀是可选的。如果指定,前缀必须是 DNS 子域:由点(`.`)分隔的一系列 DNS 标签,总共不超过 253 个字符,后跟斜杠(`/`)。 +如果省略前缀,则假定标签键对用户是私有的。 向最终用户对象添加标签的自动系统组件(例如 `kube-scheduler`,`kube-controller-manager`,`kube-apiserver`,`kubectl` 或其他第三方自动化)必须指定前缀。`kubernetes.io/` 前缀是为 Kubernetes 核心组件保留的。 + + +有效标签值必须为 63 个字符或更少,并且必须为空或以字母数字字符(`[a-z0-9A-Z]`)开头和结尾,中间可以包含破折号(`-`)、下划线(`_`)、点(`.`)和字母或数字。 + + +## 标签选择器 + + +与 [名称和 UID](/docs/user-guide/identifiers) 不同,标签不提供唯一性。通常,我们希望许多对象携带相同的标签。 + + +通过 _标签选择器_,客户端/用户可以识别一组对象。标签选择器是 Kubernetes 中的核心分组原语。 + + +API 目前支持两种类型的选择器:_基于相等性的_ 和 _基于集合的_。 +标签选择器可以由逗号分隔的多个 _需求_ 组成。在多个需求的情况下,必须满足所有要求,因此逗号分隔符充当逻辑 _与_(`&&`)运算符。 + + +空标签选择器(即,需求为零的选择器)选择集合中的每个对象。 + + +null 值的标签选择器(仅可用于可选选择器字段)不选择任何对象 +{{< note >}} + +**注意**:两个控制器的标签选择器不得在命名空间内重叠,否则它们将互相冲突。 +{{< /note >}} + + +### _基于相等性的_ 需求 + + + +_基于相等性_ 或 _不相等_ 的需求允许按标签键和值进行过滤。匹配对象必须满足所有指定的标签约束,尽管它们也可能具有其他标签。 +可接受的运算符有`=`、`==` 和 `!=` 三种。 前两个表示 _相等_(并且只是同义词),而后者表示 _不相等_。 例如: + +``` +environment = production +tier != frontend +``` + + +前者选择所有资源,其键名等于 `environment`,值等于 `production`。 +后者选择所有资源,其键名等于 `tier`,值不同于 `frontend`,所有资源都没有带有 `tier` 键的标签。 +可以使用逗号运算符来过滤 `production` 环境中的非 `frontend` 层资源:`environment=production,tier!=frontend`。 + + +基于相等性的标签要求的一种使用场景是 Pods 要指定节点选择标准。例如,下面的示例 Pod 选择带有标签 "`accelerator=nvidia-tesla-p100`"。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: cuda-test +spec: + containers: + - name: cuda-test + image: "k8s.gcr.io/cuda-vector-add:v0.1" + resources: + limits: + nvidia.com/gpu: 1 + nodeSelector: + accelerator: nvidia-tesla-p100 +``` + + +### _基于集合_ 的需求 + + +_基于集合_ 的标签需求允许您通过一组值来过滤键。支持三种操作符:`in`,`notin` and `exists` (只可以用在键标识符上)。例如: + +``` +environment in (production, qa) +tier notin (frontend, backend) +partition +!partition +``` + + + +第一个示例选择了所有键等于 `environment` 并且值等于 `production` 或者 `qa` 的资源。 + + + +第二个示例选择了所有键等于 `tier` 并且值不等于 `frontend` 或者 `backend` 的资源,以及所有没有 `tier` 键标签的资源。 + + + +第三个示例选择了所有包含了有 `partition` 标签的资源;没有校验它的值。 + + + +第三个示例选择了所有没有 `partition` 标签的资源;没有校验它的值。 + + +类似地,逗号分隔符充当 _AND_ 运算符。因此,使用 `partition` 键(无论为何值)和 `environment` 不同于 `qa` 来过滤资源可以使用 `partition,environment notin(qa)` 来实现。 + + + +_基于集合_ 的标签选择器是相等标签选择器的一般形式,因为 `environment = production` 等同于 `environment in(production)`;`!=` 和 `notin` 也是类似的。 + + +_基于集合_ 的要求可以与基于 _相等_ 的要求混合使用。例如:`partition in (customerA, customerB),environment!=qa`。 + +## API + + +### LIST 和 WATCH 过滤 + + +LIST and WATCH 操作可以使用查询参数指定标签选择器过滤一组对象。两种需求都是允许的。(这里显示的是它们出现在 URL 查询字符串中) + + + * _基于相等性_ 的需求: `?labelSelector=environment%3Dproduction,tier%3Dfrontend` + * _基于集合_ 的需求: `?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29` + + +两种标签选择器都可以通过 REST 客户端用于 list 或者 watch 资源。例如,使用 `kubectl` 定位 `apiserver`,可以使用 _基于相等性_ 的标签选择器可以这么写: + + +```shell +$ kubectl get pods -l environment=production,tier=frontend +``` + + +或者使用 _基于集合的_ 需求: + +```shell +$ kubectl get pods -l 'environment in (production),tier in (frontend)' +``` + + +正如刚才提到的,_基于集合_ 的需求更具有表达力。例如,它们可以实现值的 _或_ 操作: + +```shell +$ kubectl get pods -l 'environment in (production, qa)' +``` + + +或者通过 _exists_ 运算符限制不匹配: + +```shell +$ kubectl get pods -l 'environment,environment notin (frontend)' +``` + + +### 在 API 对象上设置引用 + +一些 Kubernetes 对象,例如 [`services`](/docs/user-guide/services) 和 [`replicationcontrollers`](/docs/user-guide/replication-controller) ,也使用了标签选择器去指定了其他资源的集合,例如 [pods](/docs/user-guide/pods)。 + + +#### Service 和 ReplicationController + +一个 `Service` 指向的一组 pods 是由标签选择器定义的。同样,一个 `ReplicationController` 应该管理的 pods 的数量也是由标签选择器定义的。 + +两个对象的标签选择器都是在 `json` 或者 `yaml` 文件中使用映射定义的,并且只支持 _基于相等性_ 需求的选择器: + +```json +"selector": { + "component" : "redis", +} +``` + + +或者 + +```yaml +selector: + component: redis +``` + + +这个选择器(分别在 `json` 或者 `yaml` 格式中) 等价于 `component=redis` 或 `component in (redis)` 。 + + +#### 支持基于集合需求的资源 + +比较新的资源,例如 [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/)、[`Deployment`](/docs/concepts/workloads/controllers/deployment/)、[`Replica Set`](/docs/concepts/workloads/controllers/replicaset/) 和[`Daemon Set`](/docs/concepts/workloads/controllers/daemonset/) ,也支持 _基于集合的_ 需求。 + +```yaml +selector: + matchLabels: + component: redis + matchExpressions: + - {key: tier, operator: In, values: [cache]} + - {key: environment, operator: NotIn, values: [dev]} +``` + + + +`matchLabels` 是由 `{key,value}` 对组成的映射。`matchLabels` 映射中的单个 `{key,value }` 等同于 `matchExpressions` 的元素,其 `key`字段为 "key",`operator` 为 "In",而 `values` 数组仅包含 "value"。`matchExpressions` 是 pod 选择器要求的列表。有效的运算符包括 In,NotIn,Exists 和 DoesNotExist。在 In 和 NotIn 的情况下,设置的值必须是非空的。来自 `matchLabels` 和 `matchExpressions` 的所有要求都是合在一起 -- 它们必须都满足才能匹配。 + + +#### 选择节点集 + + +通过标签进行选择的一个用例是确定节点集,方便 pod 调度。 +有关更多信息,请参阅 [选择节点](/docs/concepts/configuration/assign-pod-node/) 上的文档。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/overview/working-with-objects/names.md b/content/zh/docs/concepts/overview/working-with-objects/names.md new file mode 100644 index 0000000000000..4645df7e15816 --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/names.md @@ -0,0 +1,66 @@ +--- +title: 名称 +content_template: templates/concept +weight: 20 +--- + + + +{{% capture overview %}} + +Kubernetes REST API 中的所有对象都通过名称和 UID 明确标识。 + + + +对于用户提供的非惟一属性,Kubernetes 提供 [标签](/docs/user-guide/labels) 和 +[注解](/docs/concepts/overview/working-with-objects/annotations/)。 + + + +查看 [标识设计文档](https://git.k8s.io/community/contributors/design-proposals/architecture/identifiers.md) 获取名称和 UID 的精确语法规则。 + + + +{{% /capture %}} + + +{{% capture body %}} + +## 名称 + + + +{{< glossary_definition term_id="name" length="all" >}} + +按照惯例,Kubernetes 资源的名称最长可达 253 个字符,并由小写字母、数字、 “-” 和 “.” 组成,但某些资源可能有更具体的限制。 + + + +## UID + + + +{{< glossary_definition term_id="uid" length="all" >}} + +{{% /capture %}} diff --git a/content/zh/docs/concepts/overview/working-with-objects/namespaces.md b/content/zh/docs/concepts/overview/working-with-objects/namespaces.md new file mode 100644 index 0000000000000..59c8849170d61 --- /dev/null +++ b/content/zh/docs/concepts/overview/working-with-objects/namespaces.md @@ -0,0 +1,219 @@ +--- +title: 命名空间 +content_template: templates/concept +weight: 30 +--- + + +{{% capture overview %}} + +Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 +这些虚拟集群被称为命名空间。 + + +{{% /capture %}} + +{{% capture body %}} + +## 何时使用多个命名空间 + + +命名空间适用于存在很多跨多个团队或项目的用户的场景。 +对于只有几到几十个用户的集群,根本不需要创建或考虑命名空间。 + + +当您需要命名空间提供的特性时,请开始使用它们。 + + +命名空间为名称提供了一个范围。 +资源的名称需要在命名空间内是惟一的,但不能跨命名空间。 + + +命名空间是在多个用户之间划分集群资源的一种方法(通过[资源配额](/docs/concepts/policy/resource-quotas/))。 + + +在 Kubernetes 未来版本中,相同命名空间中的对象默认将具有相同的访问控制策略。 + + +不需要使用多个命名空间来分隔轻微不同的资源,例如同一软件的不同版本: +使用[标签](/docs/user-guide/labels)来区分同一命名空间中的不同资源。 + + +## 使用命名空间 + + +命名空间的创建和删除已在[命名空间的管理指南文档](/docs/admin/namespaces)中进行了描述。 + + +### 查看命名空间 + + +您可以使用以下命令列出集群中现存的命名空间: + + +```shell +$ kubectl get namespaces +NAME STATUS AGE +default Active 1d +kube-system Active 1d +kube-public Active 1d +``` + +Kubernetes 会创建三个初始命名空间: + + + * `default` 没有指明使用其它命名空间的对象所使用的默认命名空间 + + * `default` The default namespace for objects with no other namespace + --> + * `kube-system` Kubernetes 系统创建对象所使用的命名空间 + + * `kube-system` The namespace for objects created by the Kubernetes system + --> + * `kube-public` 这个命名空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。这个命名空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。这个命名空间的公共方面只是一种约定,而不是要求。 + + * `kube-public` This namespace is created automatically and is readable by all users (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. + --> + +### 为请求设置命名空间 + + +要临时设置请求的命名空间,请使用 `--namespace` 参数。 + + +例如: + + +```shell +$ kubectl --namespace= run nginx --image=nginx +$ kubectl --namespace= get pods +``` + +### 设置命名空间首选项 + + +您可以永久保存该上下文中所有后续 kubectl 命令使用的命名空间。 + + +```shell +$ kubectl config set-context $(kubectl config current-context) --namespace= +# Validate it +$ kubectl config view | grep namespace: +``` + +## 命名空间和 DNS + + +当您创建一个[服务](/docs/user-guide/services)时,Kubernetes 会创建一个相应的[DNS 条目](/docs/concepts/services-networking/dns-pod-service/)。 + + +该条目的形式是 `..svc.cluster.local`, +这意味着如果容器只使用 ``,它将被解析到本地命名空间的服务。 + + +这对于跨多个命名空间(如开发、分级和生产)使用相同的配置非常有用。 + +This is useful for using the same configuration across +multiple namespaces such as Development, Staging and Production. +--> +如果您希望跨命名空间访问,则需要使用完全限定域名(FQDN)。 + + +## 并非所有对象都在命名空间中 + + +大多数 kubernetes 资源(例如 Pod、服务、副本控制器等)都位于某些命名空间中。 +但是命名空间资源本身并不在命名空间中。 + + +而且底层资源,例如[节点](/docs/admin/node)和持久化卷不属于任何命名空间。 + + +查看哪些 Kubernetes 资源在命名空间中,哪些不在命名空间中: + + +```shell +# In a namespace +$ kubectl api-resources --namespaced=true + +# Not in a namespace +$ kubectl api-resources --namespaced=false +``` + +{{% /capture %}} diff --git a/content/zh/docs/concepts/policy/_index.md b/content/zh/docs/concepts/policy/_index.md new file mode 100644 index 0000000000000..a724a7dd475c2 --- /dev/null +++ b/content/zh/docs/concepts/policy/_index.md @@ -0,0 +1,11 @@ +--- +title: "策略" +weight: 160 +--- + + diff --git a/content/zh/docs/concepts/services-networking/_index.md b/content/zh/docs/concepts/services-networking/_index.md new file mode 100644 index 0000000000000..905f25af01b37 --- /dev/null +++ b/content/zh/docs/concepts/services-networking/_index.md @@ -0,0 +1,11 @@ +--- +title: "服务、负载均衡和联网" +weight: 80 +--- + + diff --git a/content/zh/docs/concepts/services-networking/ingress-controllers.md b/content/zh/docs/concepts/services-networking/ingress-controllers.md new file mode 100644 index 0000000000000..5841f7411ec3b --- /dev/null +++ b/content/zh/docs/concepts/services-networking/ingress-controllers.md @@ -0,0 +1,124 @@ +--- +title: Ingress 控制器 +content_template: templates/concept +weight: 40 +--- + + +{{% capture overview %}} + +为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。 + +与其他类型的控制器不同,它们是作为 `kube-controller-manager` 二进制文件的一部分运行的,而 Ingress 控制器不是随集群自动启动的。 +通过此页面可选择最适合您的集群的 ingress 控制器实现。 + +Kubernetes 作为一个项目,目前支持和维护 [GCE](https://git.k8s.io/ingress-gce/README.md) 和 + [nginx](https://git.k8s.io/ingress-nginx/README.md) 控制器。 + +{{% /capture %}} + +{{% capture body %}} + + +## 其他控制器 + +* [Ambassador](https://www.getambassador.io/) API 网关, 一个基于 [Envoy](https://www.envoyproxy.io) 的 ingress + 控制器,有着来自 [Datawire](https://www.datawire.io/) [社区](https://www.getambassador.io/docs)或[商业](https://www.getambassador.io/pro/)的支持。 +* [AppsCode Inc.](https://appscode.com) 为最广泛使用的基于 [HAProxy](http://www.haproxy.org/) 的 ingress 控制器 [Voyager](https://appscode.com/products/voyager) 提供支持和维护. +* [Contour](https://github.com/heptio/contour) 是一个基于 [Envoy](https://www.envoyproxy.io) 的 ingress 控制器,它由 Heptio 提供和支持。 +* Citrix 为其硬件(MPX),虚拟化(VPX)和 [免费容器化 (CPX) ADC](https://www.citrix.com/products/citrix-adc/cpx-express.html) 提供了一个 [Ingress 控制器](https://github.com/citrix/citrix-k8s-ingress-controller),用于[裸金属](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment/baremetal)和[云](https://github.com/citrix/citrix-k8s-ingress-controller/tree/master/deployment)部署。 +* F5 Networks 为 [用于 Kubernetes 的 F5 BIG-IP 控制器](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest)提供[支持和维护](https://support.f5.com/csp/article/K86859508)。 +* [Gloo](https://gloo.solo.io) 是一个开源的基于 [Envoy](https://www.envoyproxy.io) 的 ingress 控制器,它提供了 API 网关功能,有着来自 [solo.io](https://www.solo.io) 的企业级支持。 +* 基于 [HAProxy](http://www.haproxy.org/) 的 ingress 控制器 + [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress), + [用于 Kubernetes 的 HAProxy Ingress 控制器](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/)这篇博文提到它。 + [HAProxy Technologies](https://www.haproxy.com/) 为 HAProxy 企业版和 + ingress 控制器 [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) 提供支持和维护。 +* 基于 [Istio](https://istio.io/) 的 ingress 控制器[控制 Ingress 流量](https://istio.io/docs/tasks/traffic-management/ingress/)。 +* [Kong](https://konghq.com/) 为[用于 Kubernetes 的 Kong Ingress 控制器](https://github.com/Kong/kubernetes-ingress-controller) 提供[社区](https://discuss.konghq.com/c/kubernetes)或[商业](https://konghq.com/kong-enterprise/)支持和维护。 +* [NGINX, Inc.](https://www.nginx.com/) 为[用于 Kubernetes 的 NGINX Ingress 控制器](https://www.nginx.com/products/nginx/kubernetes-ingress-controller)提供支持和维护。 +* [Traefik](https://github.com/containous/traefik) 是一个全功能的 ingress 控制器 + ([Let's Encrypt](https://letsencrypt.org),secrets,http2,websocket),并且它也有来自 [Containous](https://containo.us/services) 的商业支持。 + + +## 使用多个 Ingress 控制器 + +你可以在集群中部署[任意数量的 ingress 控制器](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers)。 +创建 ingress 时,应该使用适当的 +[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster) 注解每个 ingress +以表明在集群中如果有多个 ingress 控制器时,应该使用哪个 ingress 控制器。 + +如果不定义 `ingress.class`,云提供商可能使用默认的 ingress 控制器。 + +理想情况下,所有 ingress 控制器都应满足此规范,但各种 ingress 控制器的操作略有不同。 + +{{< note >}} + +确保您查看了 ingress 控制器的文档,以了解选择它的注意事项。 +{{< /note >}} + +{{% /capture %}} + +{{% capture whatsnext %}} + +* 了解更多关于 [Ingress](/docs/concepts/services-networking/ingress/)。 +* [在 Minikube 上使用 NGINX 控制器安装 Ingress](/docs/tasks/access-application-cluster/ingress-minikube)。 +{{% /capture %}} diff --git a/content/zh/docs/concepts/services-networking/ingress.md b/content/zh/docs/concepts/services-networking/ingress.md new file mode 100644 index 0000000000000..6fdb5df8c8728 --- /dev/null +++ b/content/zh/docs/concepts/services-networking/ingress.md @@ -0,0 +1,674 @@ +--- +reviewers: +- bprashanth +title: Ingress +content_template: templates/concept +weight: 40 +--- + +{{% capture overview %}} +{{< glossary_definition term_id="ingress" length="all" >}} +{{% /capture %}} + +{{% capture body %}} + + + +## 专用术语 + +在本文档中,您将看到一些有时在其他地方可互换使用的术语,这些术语可能会引起混淆。 本节试图澄清它们 + +* 节点:Kubernetes 集群中的单个虚拟或物理机器。 +* 集群:互联网防火墙保护下的一组节点,它们是 Kubernetes 管理的主要计算资源。 +* 边缘路由器:为集群强制执行防火墙策略的路由器。这可以是由云提供商管理的网关或物理硬件。 +* 集群网络:一组逻辑或物理的链接,根据 [Kubernetes 网络模型](/docs/concepts/cluster-administration/networking/) 在集群内实现通信。集群网络的例子包括 覆盖网络,例如 [flannel](https://github.com/coreos/flannel#flannel);或者SDN,例如 [OVS](https://www.openvswitch.org/)。 +* 服务:Kubernetes [服务](/docs/concepts/services-networking/service/) 使用标签选择器标识一组 Pod。除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP。 + + + +## Ingress 是什么? + +通常,服务 和 Pod 具有仅能在集群网络内路由的 IP 地址。在边缘路由器结束的所有流量都被丢弃或转发到别处。从概念上讲,这可能看起来像: + +```none + internet + | + ------------ + [ Services ] +``` + + + +Ingress 是允许连接到集群 Service 的规则集合。 + +``` + 互联网 + | + [ Ingress ] + --|-----|-- + [ Services ] +``` + + + +它可以被配置为提供外部可访问的URL、负载均衡流量、终止SSL、提供基于名称的虚拟托管等等。 +用户通过向 API 服务器 POST Ingress 资源来请求 Ingress。 +[Ingress 控制器](#ingress-controllers) 负责实现 Ingress,它通常使用负载均衡器,不过它也可以配置边缘路由器或其他前端,从而帮助用户以 HA 方式处理流量。 + + + +## 环境准备 + +在开始使用 Ingress 资源之前,有一些事情您应该了解。 +Ingress 是 beta 资源,在 1.1 之前的任何 Kubernetes 版本中都不可用。 +您需要一个 Ingress 控制器来满足 Ingress,否则简单地创建资源将不起作用。 + +GCE/Google Kubernetes Engine 是在主节点上部署 Ingress 控制器。 +您可以在 Pod 中部署任意数量的自定义 Ingress 控制器。 +您必须使用适当的类来注释每个 Ingress,如[这里](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) 和 [这里](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class) 所示。 + +一定要检查一下这个控制器的 [beta 限制](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations)。 +在 GCE/Google Kubernetes Engine 之外的环境中,需要将[控制器部署](https://git.k8s.io/ingress-nginx/README.md) 为 Pod。 + + + +## Ingress 资源 + +最小的 Ingress 可能看起来像这样: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test-ingress + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - http: + paths: + - path: /testpath + backend: + serviceName: test + servicePort: 80 +``` + + + +*如果尚未配置 [Ingress 控制器](#ingress-controllers),则向 API 服务器 POST 操作将没有任何效果。* + + +__1-6 行__: 与其他 Kubernetes 对象配置一样,Ingress 需要 `apiVersion`、`kind`、和 `metadata` 字段。 +有关使用配置文件的一般信息,请参见 +[部署应用](/docs/tasks/run-application/run-stateless-application-deployment/)、 +[配置容器](/docs/tasks/configure-pod-container/configure-pod-configmap/)、 +[管理资源](/docs/concepts/cluster-administration/manage-deployment/) +和 [ingress 配置重写](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md)。 + + +__7-9 行__: Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) 具有配置负载均衡器或代理服务器所需的所有信息。 +最重要的是,它包含与所有传入请求相匹配的规则列表。目前,Ingress 资源仅支持 HTTP 规则。 + + + +__10-11 行__: 每个 HTTP 规则都包含以下信息:主机(例如:foo.bar.com,在本例中默认为 * ),路径列表(例如:/testpath),每个路径都有一个关联的后端(test:80)。 +在负载均衡器将流量路由到后端之前,主机和路径都必须与传入请求的规则匹配。 + +__12-14 行__: 如[services doc](/docs/concepts/services-net./service/)中所述,后端(endpoint)是 “Service:port” 的组合。 +Ingress 流量通常被直接发送到与后端相匹配的端点。 + +__全局参数__: 为了简单起见,Ingress 示例没有全局参数,有关资源的完整定义请参见 [API引用](https://releases.k8s.io/{{< param "githubbranch" >}}/staging/src/k8s.io/api/extensions/v1beta1/types.go)。 +您可以指定全局默认的后端,这样的话,当请求与 spec 中的路径不匹配时,就会被转发到 Ingress 控制器的默认后端。 + + + +## Ingress 控制器 + +为了使 Ingress 资源正常工作,集群必须有 Ingress 控制器运行。 +这不同于其他类型的控制器,它们通常作为 `kube-controller-manager` 二进制文件的一部分运行,并且通常作为集群创建的一部分自动启动。 +请选择最适合您的集群的 Ingress 控制器,或者实现一个新的 Ingress 控制器。 + + + +* Kubernetes 当前支持并维护 [GCE](https://git.k8s.io/ingress-gce/README.md) 和 [nginx](https://git.k8s.io/ingress-nginx/README.md) 控制器。 +* F5 Networks 为 [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest) 提供[支持和维护](https://support.f5.com/csp/article/K86859508)。 +* [Kong](https://konghq.com/) 为 [Kong Ingress Controller for Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/) 提供 [社区版](https://discuss.konghq.com/c/kubernetes) 或 [商业版](https://konghq.com/api-customer-success/) 支持和维护。 +* [Traefik](https://github.com/containous/traefik) 是个全功能的 Ingress 控制器。 +([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket...), 它也伴随着 [Containous](https://containo.us/services) 的商业支持。 +* [NGINX, Inc.](https://www.nginx.com/) 为 [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller) 提供支持和维护。 +* [HAProxy](http://www.haproxy.org/) 是 Ingress 控制器 [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) 的基础, 在这个博客中有提到它 [HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/)。 +* [Istio](https://istio.io/) 是 Ingress 控制器 [Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/) 的基础。 + +{{< note >}} +**注意:** 请检查你的控制器的文档以找到其特定的支持策略。 +{{< /note >}} + + + +## 在您开始之前 + +下面的文档描述了通过Ingress资源公开的一组跨平台特性。 +理想情况下,所有 Ingress 控制器都应该满足这个规范,但是我们还没有。 +我们现在支持并维护 [GCE](https://git.k8s.io/ingress-gce/README.md) 和 [nginx](https://git.k8s.io/ingress-nginx/README.md) 控制器。 +如果您使用 F5 BIG-IP 控制器,请参考 [使用 BIG-IP 控制器作为 Kubernetes Ingress 控制器](http://clouddocs.f5.com/containers/latest/kubernetes/kctlr-k8s-ingress-ctlr.html)。 + + + +{{< note >}} +**注意:** 请您一定要查看您的控制器的特定文档,以便您能理解这些警告。 +{{< /note >}} + + + +## Ingress 的类型 + +### 单服务 Ingress + +现有的 Kubernetes 概念允许您暴露单个 Service (查看 [替代方案](#alternatives)),同样您也可以使用 Ingress 来实现,具体方法是指定一个没有规则的 *默认后端(default backend)*。 + + +{{< codenew file="service/networking/ingress.yaml" >}} + + + +如果您用 `kubectl create -f`创建它,你应该看到: + + +```shell +kubectl get ingress test-ingress +``` + +```shell +NAME HOSTS ADDRESS PORTS AGE +test-ingress * 107.178.254.228 80 59s +``` + + + +其中 `107.178.254.228` 是 Ingress 控制器为该 Ingress 分配的 IP 该。 + + + +### 简单分列 + +如前所述,Kubernetes 中 Pod 的 IP 仅在集群网络上可见,所以我们需要在集群网络的边缘接收下行流量并将其代理到正确的端点。 +这个组件通常是一个高可用的负载均衡器。Ingress 允许您将负载均衡器的数量降至最低。例如,这样的设置: + +```shell +foo.bar.com -> 178.91.123.132 -> / foo s1:80 + / bar s2:80 +``` + + + +可能需要一个 Ingress 就像: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test + annotations: + nginx.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 +``` + + + +当您使用 `kubectl create -f` 创建 Ingress 时: + +```shell +kubectl describe ingress test +``` + +```shell +Name: test +Namespace: default +Address: 178.91.123.132 +Default backend: default-http-backend:80 (10.8.2.3:8080) +Rules: + Host Path Backends + ---- ---- -------- + foo.bar.com + /foo s1:80 (10.8.0.90:80) + /bar s2:80 (10.8.0.91:80) +Annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal ADD 22s loadbalancer-controller default/test +``` + + + +Ingress 控制器将提供实现特定的负载均衡器来满足 Ingress,只要 Service (`s1`,`s2`) 存在。 +当它这样做了,你会在地址栏看到负载平衡器的地址。 + +{{< note >}} + +**注意:** 如果需要,你需要创建一个默认的 HTTP 后端 [Service](/docs/concepts/services-networking/service/)。 +{{< /note >}} + + + + +### 基于名称的虚拟托管 + +基于名称的虚拟主机为同一个 IP 地址使用多个主机名。 + +```none +foo.bar.com --| |-> foo.bar.com s1:80 + | 178.91.123.132 | +bar.foo.com --| |-> bar.foo.com s2:80 +``` + + + +下面的 Ingress 让后台的负载均衡器基于 [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 +``` + + + +__默认后端__: 一个没有规则的 Ingress,如前面部分所示,它将所有流量发送到单个默认后端。 +通过指定一组规则*和*默认后端,您可以使用相同的技术来告诉负载均衡器在哪里找到网站的 404 页面。 +如果 Ingress 中的主机与请求头中的主机不匹配,和/或没有路径与请求的 URL 匹配,则流量被路由到默认后端。 + + + +### TLS + +您可以通过指定包含TLS私钥和证书的 [secret](/docs/concepts/configuration/secret) 来加密 Ingress。 +目前,Ingress 只支持单个 TLS 端口,443,并假定 TLS 终止。 +如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。 +TLS Secret 必须包含名为 `tls.crt` 和 `tls.key` 的密钥,这些密钥包含用于 TLS 的证书和私钥,例如: + +```yaml +apiVersion: v1 +data: + tls.crt: base64 encoded cert + tls.key: base64 encoded key +kind: Secret +metadata: + name: testsecret + namespace: default +type: Opaque +``` + + + +在 Ingress 中引用此 Secret 将会告诉 Ingress 控制器使用 TLS 保护从客户端到负载均衡器的通道: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: no-rules-map +spec: + tls: + - secretName: testsecret + backend: + serviceName: s1 + servicePort: 80 +``` + + + +注意,各种 Ingress 控制器所支持的 TLS 功能之间存在间隙。请参阅有关文件 +[nginx](https://git.k8s.io/ingress-nginx/README.md#https), +[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), +或任何其他平台特定的 Ingress 控制器,以了解 TLS 如何在您的环境中工作。 + + + +### 负载均衡 + +Ingress控制器使用一些适用于所有 Ingress 的负载均衡策略设置进行自举,例如负载平衡算法、后端权重方案等。 +更高级的负载平衡概念(例如,持久会话、动态权重)尚未通过Ingress公开。 +您仍然可以通过 [Service 负载均衡器](https://github.com/kubernetes/ingress-nginx) 获得这些特性。 +随着时间的推移,我们计划将跨平台应用的负载平衡模式提取到 Ingress 资源中。 + + + +值得注意的是,即使健康检查不是通过 Ingress 直接暴露的,但是在 Kubernetes 中存在并行概念,比如 [就绪检查](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),它允许您实现相同的最终结果。 +请检查控制器说明文档,以了解他们是怎样实现健康检查的 ( +[nginx](https://git.k8s.io/ingress-nginx/README.md), +[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))。 + + + + +## 更新 Ingress + +假设您想向现有的 Ingress 中添加新主机,可以通过编辑资源来更新它: + +```shell +kubectl describe ingress test +``` + +```shell +Name: test +Namespace: default +Address: 178.91.123.132 +Default backend: default-http-backend:80 (10.8.2.3:8080) +Rules: + Host Path Backends + ---- ---- -------- + foo.bar.com + /foo s1:80 (10.8.0.90:80) +Annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal ADD 35s loadbalancer-controller default/test +``` + +```shell +kubectl edit ingress test +``` + + + +这应该弹出一个编辑器与现有的 yaml,修改它来增加新的主机: + +```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 +.. +``` + + + +保存 yaml 将更新 API 服务器中的资源,这应该会告诉 Ingress 控制器来重新配置负载均衡器。 + +```shell +kubectl describe ingress test +``` + +```shell +Name: test +Namespace: default +Address: 178.91.123.132 +Default backend: default-http-backend:80 (10.8.2.3:8080) +Rules: + Host Path Backends + ---- ---- -------- + foo.bar.com + /foo s1:80 (10.8.0.90:80) + bar.baz.com + /foo s2:80 (10.8.0.91:80) +Annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal ADD 45s loadbalancer-controller default/test +``` + + + +您可以通过 `kubectl replace -f` 命令调用修改后的 Ingress yaml 文件来获得同样的结果。 + + + +## 跨可用区失败 + +用于跨故障域传播流量的技术在云提供商之间是不同的。详情请查阅相关 Ingress 控制器的文档。 +有关在联邦集群中部署 Ingress 的详细信息,请参阅联邦 [文档](/docs/concepts/cluster-administration/federation/)。 + + + + +## 未来的工作 + +*各种 HTTPS/TLS 模式的支持(例如:SNI、重加密) +*通过声明请求IP或主机名 +*合并 L4 和 L7 Ingress +*更多 Ingress 控制器 + +请跟踪 [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827)以了解关于资源演化的更多细节,以及 [Ingress repository](https://github.com/kubernetes/ingress/tree/master) 以了解关于各种 Ingress 控制器演进的更多细节。 + + + +## 替代方案 + +不直接使用 Ingress 资源,也有多种方法暴露 Service: + +* 使用 [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer) +* 使用 [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) +* 使用 [端口代理](https://git.k8s.io/contrib/for-demos/proxy-to-service) + +{{% /capture %}} + +{{% capture whatsnext %}} + +{{% /capture %}} + diff --git a/content/zh/docs/concepts/services-networking/service.md b/content/zh/docs/concepts/services-networking/service.md index 6e9705b22129a..534a01cf4700b 100644 --- a/content/zh/docs/concepts/services-networking/service.md +++ b/content/zh/docs/concepts/services-networking/service.md @@ -1,46 +1,103 @@ --- -approvers: +reviewers: - bprashanth -title: Service -redirect_from: -- "/docs/user-guide/services/" -- "/docs/user-guide/services/index.html" +title: Services +feature: + title: 服务发现与负载均衡 + description: > + 无需修改您的应用程序即可使用陌生的服务发现机制。Kubernetes 为容器提供了自己的 IP 地址和一个 DNS 名称,并且可以在它们之间实现负载平衡。 + +content_template: templates/concept +weight: 10 --- + +{{% capture overview %}} + + + Kubernetes [`Pod`](/docs/user-guide/pods) 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过 [`ReplicaSets`](/docs/concepts/workloads/controllers/replicaset/) 能够动态地创建和销毁 `Pod`(例如,需要进行扩缩容,或者执行 [滚动升级](/docs/user-guide/kubectl/v1.7/#rolling-update))。 每个 `Pod` 都会获取它自己的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。 这会导致一个问题:在 Kubernetes 集群中,如果一组 `Pod`(称为 backend)为其它 `Pod` (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 `Pod` 中的哪些 backend 呢? + +关于 `Services` -关于 `Service` - - + Kubernetes `Service` 定义了这样一种抽象:逻辑上的一组 `Pod`,一种可以访问它们的策略 —— 通常称为微服务。 这一组 `Pod` 能够被 `Service` 访问到,通常是通过 [`Label Selector`](/docs/concepts/overview/working-with-objects/labels/#label-selectors)(查看下面了解,为什么可能需要没有 selector 的 `Service`)实现的。 - + 举个例子,考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪个 backend 副本。 然而组成这一组 backend 程序的 `Pod` 实际上可能会发生变化,frontend 客户端不应该也没必要知道,而且也不需要跟踪这一组 backend 的状态。 `Service` 定义的抽象能够解耦这种关联。 - + 对 Kubernetes 集群中的应用,Kubernetes 提供了简单的 `Endpoints` API,只要 `Service` 中的一组 `Pod` 发生变更,应用程序就会被更新。 对非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问 `Service`,再由 `Service` 重定向到 backend `Pod`。 -{{< toc >}} +{{% /capture %}} +{{% capture body %}} -## 定义 Service - + +## 定义 Service 一个 `Service` 在 Kubernetes 中是一个 REST 对象,和 `Pod` 类似。 像所有的 REST 对象一样, `Service` 定义可以基于 POST 方式,请求 apiserver 创建新的实例。 @@ -60,13 +117,29 @@ spec: targetPort: 9376 ``` - + 上述配置将创建一个名称为 “my-service” 的 `Service` 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 `"app=MyApp"` 的 `Pod` 上。 这个 `Service` 将被指派一个 IP 地址(通常称为 “Cluster IP”),它会被服务的代理使用(见下面)。 该 `Service` 的 selector 将会持续评估,处理结果将被 POST 到一个名称为 “my-service” 的 `Endpoints` 对象上。 - + 需要注意的是, `Service` 能够将一个接收端口映射到任意的 `targetPort`。 默认情况下,`targetPort` 将被设置为与 `port` 字段相同的值。 @@ -75,16 +148,32 @@ spec: 对于部署和设计 `Service` ,这种方式会提供更大的灵活性。 例如,可以在 backend 软件下一个版本中,修改 Pod 暴露的端口,并不会中断客户端的调用。 - + Kubernetes `Service` 能够支持 `TCP` 和 `UDP` 协议,默认 `TCP` 协议。 - +{{< note >}} +自 Kubernetes 1.12 以来,SCTP 的支持是 alpha 功能。 +{{< /note >}} + + ### 没有 selector 的 Service - - Servcie 抽象了该如何访问 Kubernetes `Pod`,但也能够抽象其它类型的 backend,例如: * 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。 @@ -105,6 +194,10 @@ spec: targetPort: 9376 ``` + 由于这个 `Service` 没有 selector,就不会创建相关的 `Endpoints` 对象。可以手动将 `Service` 映射到指定的 `Endpoints`: @@ -120,57 +213,76 @@ subsets: - port: 9376 ``` - - -注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。 - - + + +{{< note >}} +注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。它们不能是其他 Kubernetes 服务的集群 IP,因为 `kube-proxy` 组件不支持虚拟 IP 作为目的地。 +{{< /note >}} + + 访问没有 selector 的 `Service`,与有 selector 的 `Service` 的原理相同。请求将被路由到用户定义的 Endpoint(该示例中为 `1.2.3.4:9376`)。 - - -ExternalName `Service` 是 `Service` 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 -相反地,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。 - -```yaml -kind: Service -apiVersion: v1 -metadata: - name: my-service - namespace: prod -spec: - type: ExternalName - externalName: my.database.example.com -``` - - - -当查询主机 `my-service.prod.svc.CLUSTER`时,集群的 DNS 服务将返回一个值为 `my.database.example.com` 的 `CNAME` 记录。 -访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。 -如果后续决定要将数据库迁移到 Kubernetes 集群中,可以启动对应的 Pod,增加合适的 Selector 或 Endpoint,修改 `Service` 的 `type`。 - - + + +ExternalName `Service` 是 `Service` 的特例,它没有 selector,也没有使用 DNS 名称代替。 +有关更多信息,请参阅本文档后面的[`ExternalName`](#externalname)。 + + ## VIP 和 Service 代理 +在 Kubernetes 集群中,每个 Node 运行一个 `kube-proxy` 进程。`kube-proxy` 负责为 `Service` 实现了一种 VIP(虚拟 IP)的形式,而不是 [`ExternalName`](#externalname) 的形式。 - -在 Kubernetes 集群中,每个 Node 运行一个 `kube-proxy` 进程。`kube-proxy` 负责为 `Service` 实现了一种 VIP(虚拟 IP)的形式,而不是 `ExternalName` 的形式。 -在 Kubernetes v1.0 版本,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默认的运行模式。 -从 Kubernetes v1.2 起,默认就是 iptables 代理。 +在 Kubernetes v1.0 版本,`Services` 是 "L4" (IP 层上的 TCP/UDP) 构造,代理完全在 userspace。在 Kubernetes v1.1 版本,新增了 `Ingress` API (beta) "L 7"(HTTP) 服务与 iptables 代理,自 Kubernetes v1.2 以来成为默认的操作模式。 +在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理。 在 Kubernetes v1.0 版本,`Service` 是 “4层”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了 `Ingress` API(beta 版),用来表示 “7层”(HTTP)服务。 - + ### userspace 代理模式 - - 这种模式,kube-proxy 会监视 Kubernetes master 对 `Service` 对象和 `Endpoints` 对象的添加和移除。 对每个 `Service`,它会在本地 Node 上打开一个端口(随机选择)。 任何连接到“代理端口”的请求,都会被代理到 `Service` 的backend `Pods` 中的某个上面(如 `Endpoints` 所报告的一样)。 @@ -190,12 +302,24 @@ spec: ![userspace代理模式下Service概览图](/images/docs/services-userspace-overview.svg) - + ### iptables 代理模式 - - 这种模式,kube-proxy 会监视 Kubernetes master 对 `Service` 对象和 `Endpoints` 对象的添加和移除。 对每个 `Service`,它会安装 iptables 规则,从而捕获到达该 `Service` 的 `clusterIP`(虚拟 IP)和端口的请求,进而将请求重定向到 `Service` 的一组 backend 中的某个上面。 对于每个 `Endpoints` 对象,它也会安装 iptables 规则,这个规则会选择一个 backend `Pod`。 @@ -214,7 +338,68 @@ spec: ![iptables代理模式下Service概览图](/images/docs/services-iptables-overview.svg) - + + + ## 多端口 Service @@ -242,23 +427,43 @@ spec: targetPort: 9377 ``` - + ## 选择自己的 IP 地址 - - 在 `Service` 创建的请求中,可以通过设置 `spec.clusterIP` 字段来指定自己的集群 IP 地址。 比如,希望替换一个已经已存在的 DNS 条目,或者遗留系统已经配置了一个固定的 IP 且很难重新配置。 用户选择的 IP 地址必须合法,并且这个 IP 地址在 `service-cluster-ip-range` CIDR 范围内,这对 API Server 来说是通过一个标识来指定的。 如果 IP 地址不合法,API Server 会返回 HTTP 状态码 422,表示值不合法。 + ### 为何不使用 round-robin DNS? - 一个不时出现的问题是,为什么我们都使用 VIP 的方式,而不使用标准的 round-robin DNS,有如下几个原因: * 长久以来,DNS 库都没能认真对待 DNS TTL、缓存域名查询结果 @@ -267,20 +472,42 @@ spec: 我们尽力阻止用户做那些对他们没有好处的事情,如果很多人都来问这个问题,我们可能会选择实现它。 - + ## 服务发现 - - Kubernetes 支持2种基本的服务发现模式 —— 环境变量和 DNS。 - - + ### 环境变量 - - 当 `Pod` 运行在 `Node` 上,kubelet 会为每个活跃的 `Service` 添加一组环境变量。 它同时支持 [Docker links兼容](https://docs.docker.com/userguide/dockerlinks/) 变量(查看 [makeLinkVariables](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/kubelet/envvars/envvars.go#L49))、简单的 `{SVCNAME}_SERVICE_HOST` 和 `{SVCNAME}_SERVICE_PORT` 变量,这里 `Service` 的名称需大写,横线被转换成下划线。 @@ -301,9 +528,29 @@ REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 *这意味着需要有顺序的要求* —— `Pod` 想要访问的任何 `Service` 必须在 `Pod` 自己之前被创建,否则这些环境变量就不会被赋值。DNS 并没有这个限制。 + - +### DNS 一个可选(尽管强烈推荐)[集群插件](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/README.md) 是 DNS 服务器。 DNS 服务器监视着创建新 `Service` 的 Kubernetes API,从而为每一个 `Service` 创建一组 DNS 记录。 @@ -326,7 +573,20 @@ Kubernetes 也支持对端口名称的 DNS SRV(Service)记录。 Kubernetes DNS 服务器是唯一的一种能够访问 `ExternalName` 类型的 Service 的方式。 更多信息可以查看[DNS Pod 和 Service](/docs/concepts/services-networking/dns-pod-service/)。 - + ## Headless Service @@ -345,7 +605,12 @@ Kubernetes DNS 服务器是唯一的一种能够访问 `ExternalName` 类型的 对这类 `Service` 并不会分配 Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 `Service` 是否定义了 selector。 - + ### 配置 Selector @@ -353,7 +618,15 @@ DNS 如何实现自动配置,依赖于 `Service` 是否定义了 selector。 对定义了 selector 的 Headless Service,Endpoint 控制器在 API 中创建了 `Endpoints` 记录,并且修改 DNS 配置返回 A 记录(地址),通过这个地址直接到达 `Service` 的后端 `Pod` 上。 - + ### 不配置 Selector @@ -365,7 +638,28 @@ DNS 如何实现自动配置,依赖于 `Service` 是否定义了 selector。 * `ExternalName` 类型 Service 的 CNAME 记录 * 记录:与 Service 共享一个名称的任何 `Endpoints`,以及所有其它类型 - + ## 发布服务 —— 服务类型 @@ -381,9 +675,29 @@ Kubernetes `ServiceTypes` 允许指定一个需要的类型的 Service,默认 * `NodePort`:通过每个 Node 上的 IP 和静态端口(`NodePort`)暴露服务。`NodePort` 服务会路由到 `ClusterIP` 服务,这个 `ClusterIP` 服务会自动创建。通过请求 `:`,可以从集群的外部访问一个 `NodePort` 服务。 * `LoadBalancer`:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 `NodePort` 服务和 `ClusterIP` 服务。 * `ExternalName`:通过返回 `CNAME` 和它的值,可以将服务映射到 `externalName` 字段的内容(例如, `foo.bar.example.com`)。 - 没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 `kube-dns` 才支持。 - - + 没有任何类型代理被创建。 + +{{< note >}} +您需要 CoreDNS 1.7 或更高版本才能使用 `ExternalName` 类型。 +{{< /note >}} + + ### NodePort 类型 @@ -402,12 +716,51 @@ Kubernetes `ServiceTypes` 允许指定一个需要的类型的 Service,默认 需要注意的是,Service 将能够通过 `:spec.ports[*].nodePort` 和 `spec.clusterIp:spec.ports[*].port` 而对外可见。 - + ### LoadBalancer 类型 - - 使用支持外部负载均衡器的云提供商的服务,设置 `type` 的值为 `"LoadBalancer"`,将为 `Service` 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 `Service` 的 `status.loadBalancer` 字段被发布出去。 @@ -439,7 +792,59 @@ status: 某些云提供商允许设置 `loadBalancerIP`。如果没有设置 `loadBalancerIP`,将会给负载均衡器指派一个临时 IP。 如果设置了 `loadBalancerIP`,但云提供商并不支持这种特性,那么设置的 `loadBalancerIP` 值将会被忽略掉。 - + ### AWS 内部负载均衡器 在混合云环境中,有时从虚拟私有云(VPC)环境中的服务路由流量是非常有必要的。 @@ -457,7 +862,61 @@ metadata: 在水平分割的 DNS 环境中,需要两个 `Service` 来将外部和内部的流量路由到 Endpoint 上。 - + ### AWS SSL 支持 对运行在 AWS 上部分支持 SSL 的集群,从 1.3 版本开始,可以为 `LoadBalancer` 类型的 `Service` 增加两个 annotation: @@ -490,7 +949,31 @@ HTTP 和 HTTPS 将选择7层代理:ELB 将中断与用户的连接,当转发 TCP 和 SSL 将选择4层代理:ELB 将转发流量,并不修改 Header 信息。 - + ### 外部 IP @@ -518,7 +1001,20 @@ spec: - 80.11.12.10 ``` - + ## 不足之处 @@ -536,7 +1032,20 @@ iptables 代理不会隐藏 Kubernetes 集群内部的 IP 地址,但却要求 `Type` 字段支持嵌套功能 —— 每一层需要添加到上一层里面。 不会严格要求所有云提供商(例如,GCE 就没必要为了使一个 `LoadBalancer` 能工作而分配一个 `NodePort`,但是 AWS 需要 ),但当前 API 是强制要求的。 - + ## 未来工作 @@ -549,14 +1058,37 @@ iptables 代理不会隐藏 Kubernetes 集群内部的 IP 地址,但却要求 我们打算为 `Service` 实现更加灵活的请求进入模式,这些 `Service` 包含当前 `ClusterIP`、`NodePort` 和 `LoadBalancer` 模式,或者更多。 - + ## VIP 的那些骇人听闻的细节 对很多想使用 `Service` 的人来说,前面的信息应该足够了。 然而,有很多内部原理性的内容,还是值去理解的。 - + ### 避免冲突 @@ -575,7 +1107,18 @@ Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致 为了使 `Service` 能够获取到 IP,这个映射表对象必须在注册中心存在,否则创建 `Service` 将会失败,指示一个 IP 不能被分配。 一个后台 Controller 的职责是创建映射表(从 Kubernetes 的旧版本迁移过来,旧版本中是通过在内存中加锁的方式实现),并检查由于管理员干预和清除任意 IP 造成的不合理分配,这些 IP 被分配了但当前没有 `Service` 使用它们。 - + ### IP 和 VIP @@ -584,7 +1127,22 @@ Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致 当客户端连接到 VIP 时,它们的流量会自动地传输到一个合适的 Endpoint。 环境变量和 DNS,实际上会根据 `Service` 的 VIP 和端口来进行填充。 - + #### Userspace @@ -601,7 +1159,23 @@ Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致 这意味着 `Service` 的所有者能够选择任何他们想使用的端口,而不存在冲突的风险。 客户端可以简单地连接到一个 IP 和端口,而不需要知道实际访问了哪些 `Pod`。 - + #### Iptables @@ -617,7 +1191,12 @@ Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致 不像 userspace 代理,数据包从来不拷贝到用户空间,kube-proxy 不是必须为该 VIP 工作而运行,并且客户端 IP 是不可更改的。 当流量打到 Node 的端口上,或通过负载均衡器,会执行相同的基本流程,但是在那些案例中客户端 IP 是可以更改的。 - + ## API 对象 diff --git a/content/zh/docs/concepts/storage/_index.md b/content/zh/docs/concepts/storage/_index.md index 3f2371fcb414c..1880a0aef7278 100644 --- a/content/zh/docs/concepts/storage/_index.md +++ b/content/zh/docs/concepts/storage/_index.md @@ -8,4 +8,4 @@ weight: 70 title: "Storage" weight: 70 --- ---> \ No newline at end of file +--> diff --git a/content/zh/docs/concepts/storage/dynamic-provisioning.md b/content/zh/docs/concepts/storage/dynamic-provisioning.md new file mode 100644 index 0000000000000..f9f642bfdaddd --- /dev/null +++ b/content/zh/docs/concepts/storage/dynamic-provisioning.md @@ -0,0 +1,220 @@ +--- +title: 动态卷供应 +content_template: templates/concept +weight: 40 +--- + + +{{% capture overview %}} + + +动态卷供应允许按需创建存储卷。 +如果没有动态供应,集群管理员必须手动地联系他们的云或存储提供商来创建新的存储卷, +然后在 Kubernetes 集群创建 [`PersistentVolume` 对象](/docs/concepts/storage/persistent-volumes/)来表示这些卷。 +动态供应功能消除了集群管理员预先配置存储的需要。 相反,它在用户请求时自动供应存储。 + +{{% /capture %}} + +{{% capture body %}} + + +## 背景 + + +动态卷供应的实现基于 `storage.k8s.io` API 组中的 `StorageClass` API 对象。 +集群管理员可以根据需要定义多个 `StorageClass` 对象,每个对象指定一个*卷插件*(又名 *provisioner*), +卷插件向卷供应商提供在创建卷时需要的数据卷信息及相关参数。 + + +集群管理员可以在集群中定义和公开多种存储(来自相同或不同的存储系统),每种都具有自定义参数集。 +该设计也确保终端用户不必担心存储供应的复杂性和细微差别,但仍然能够从多个存储选项中进行选择。 + + +点击[这里](/docs/concepts/storage/persistent-volumes/#storageclasses)查阅有关存储类的更多信息。 + + +## 启用动态卷供应 + + +要启用动态供应功能,集群管理员需要为用户预先创建一个或多个 `StorageClass` 对象。 +`StorageClass` 对象定义在进行动态卷供应时应使用哪个卷供应商,以及应该将哪些参数传递给该供应商。 +以下清单创建了一个存储类 "slow",它提供类似标准磁盘的永久磁盘。 + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: slow +provisioner: kubernetes.io/gce-pd +parameters: + type: pd-standard +``` + + +以下清单创建了一个 "fast" 存储类,它提供类似 SSD 的永久磁盘。 + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: fast +provisioner: kubernetes.io/gce-pd +parameters: + type: pd-ssd +``` + + +## 使用动态卷供应 + + +用户通过在 `PersistentVolumeClaim` 中包含存储类来请求动态供应的存储。 +在 Kubernetes v1.6 之前,这通过 `volume.beta.kubernetes.io/storage-class` 注解实现。 + + +然而,这个注解自 v1.6 起就不被推荐使用了。 +用户现在能够而且应该使用 `PersistentVolumeClaim` 对象的 `storageClassName` 字段。 +这个字段的值必须能够匹配到集群管理员配置的 `StorageClass` 名称(见[下面](#enabling-dynamic-provisioning))。 + + +例如,要选择 "fast" 存储类,用户将创建如下的 `PersistentVolumeClaim`: + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: claim1 +spec: + accessModes: + - ReadWriteOnce + storageClassName: fast + resources: + requests: + storage: 30Gi +``` + + +该声明会自动供应一块类似 SSD 的永久磁盘。 +在删除该声明后,这个卷也会被销毁。 + + +## 默认行为 + + +可以在群集上启用动态卷供应,以便在未指定存储类的情况下动态设置所有声明。 +集群管理员可以通过以下方式启用此行为: + + +- 标记一个 `StorageClass` 为 *默认*; +- 确保 [`DefaultStorageClass` 准入控制器](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)在 API 服务端被启用。 + + +管理员可以通过向其添加 `storageclass.kubernetes.io/is-default-class` 注解来将特定的 `StorageClass` 标记为默认。 +当集群中存在默认的 `StorageClass` 并且用户创建了一个未指定 `storageClassName` 的 `PersistentVolumeClaim` 时, +`DefaultStorageClass` 准入控制器会自动向其中添加指向默认存储类的 `storageClassName` 字段。 + + +请注意,群集上最多只能有一个 *默认* 存储类,否则无法创建没有明确指定 `storageClassName` 的 `PersistentVolumeClaim`。 + + +## 拓扑感知 + + +在[多区域](/docs/setup/multiple-zones)集群中,Pod 可以被分散到多个区域。 +单区域存储后端应该被供应到 Pod 被调度到的区域。 +这可以通过设置[卷绑定模式](/docs/concepts/storage/storage-classes/#volume-binding-mode)来实现。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/storage/storage-classes.md b/content/zh/docs/concepts/storage/storage-classes.md new file mode 100644 index 0000000000000..d15c48fad575e --- /dev/null +++ b/content/zh/docs/concepts/storage/storage-classes.md @@ -0,0 +1,1152 @@ +--- +reviewers: +- jsafrane +- saad-ali +- thockin +- msau42 +title: Storage Classes +content_template: templates/concept +weight: 30 +--- + +{{% capture overview %}} + + +本文描述了 Kubernetes 中 StorageClass 的概念。建议先熟悉 [卷](/docs/concepts/storage/volumes/) 和 +[持久卷](/docs/concepts/storage/persistent-volumes) 的概念。 + +{{% /capture %}} + +{{% capture body %}} + + +## 介绍 + +`StorageClass` 为管理员提供了描述存储 `"类"` 的方法。 +不同的`类型`可能会映射到不同的服务质量等级或备份策略,或是由群集管理员制定的任意策略。 +Kubernetes 本身并不清楚各种`类`代表的什么。这个`类`的概念在其他存储系统中有时被称为"配置文件"。 + + +## StorageClass 资源 + +每个 `StorageClass` 都包含 `provisioner`、`parameters` 和 `reclaimPolicy` 字段, +这些字段会在`StorageClass`需要动态分配 `PersistentVolume` 时会使用到。 + + +`StorageClass` 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 +当创建 `StorageClass` 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。 + + +管理员可以为没有申请绑定到特定 `StorageClass` 的 PVC 指定一个默认的`类` : +更多详情请参阅 [`PersistentVolumeClaim` 章节](#persistentvolumeclaims)。 + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: standard +provisioner: kubernetes.io/aws-ebs +parameters: + type: gp2 +reclaimPolicy: Retain +mountOptions: + - debug +volumeBindingMode: Immediate +``` + + +### 存储分配器 + +`StorageClass` 有一个分配器,用来决定使用哪个`卷插件`分配`持久化卷申领`。该字段必须指定。 + +| 卷插件 | 提供厂商 | 配置例子 | +| :--- | :---: | :---: | +| AWSElasticBlockStore | ✓ | [AWS EBS](#aws-ebs) | +| AzureFile | ✓ | [Azure File](#azure-file) | +| AzureDisk | ✓ | [Azure Disk](#azure-disk) | +| CephFS | - | - | +| Cinder | ✓ | [OpenStack Cinder](#openstack-cinder)| +| FC | - | - | +| Flexvolume | - | - | +| Flocker | ✓ | - | +| GCEPersistentDisk | ✓ | [GCE PD](#gce-pd) | +| Glusterfs | ✓ | [Glusterfs](#glusterfs) | +| iSCSI | - | - | +| Quobyte | ✓ | [Quobyte](#quobyte) | +| NFS | - | - | +| RBD | ✓ | [Ceph RBD](#ceph-rbd) | +| VsphereVolume | ✓ | [vSphere](#vsphere) | +| PortworxVolume | ✓ | [Portworx Volume](#portworx-volume) | +| ScaleIO | ✓ | [ScaleIO](#scaleio) | +| StorageOS | ✓ | [StorageOS](#storageos) | +| Local | - | [Local](#local) | + + +您不限于指定此处列出的"内置"分配器(其名称前缀为 kubernetes.io 并打包在 Kubernetes 中)。 +您还可以运行和指定外部分配器,这些独立的程序遵循由 Kubernetes 定义的 [规范](https://git.k8s.io/community/contributors/design-proposals/storage/volume-provisioning.md)。 +外部供应商的作者完全可以自由决定他们的代码保存于何处、打包方式、运行方式、使用的插件(包括 Flex)等。 +代码仓库 [kubernetes-incubator/external-storage](https://github.com/kubernetes-incubator/external-storage) +包含一个用于为外部分配器编写功能实现的类库,以及各种社区维护的外部分配器。 + + +例如,NFS 没有内部分配器,但可以使用外部分配器。一些外部分配器在代码仓库 [kubernetes-incubator/external-storage](https://github.com/kubernetes-incubator/external-storage) 中。 +也有第三方存储供应商提供自己的外部分配器。 + + +### 回收策略 + +由 `StorageClass` 动态创建的持久化卷会在的 `reclaimPolicy` 字段中指定回收策略,可以是 +`Delete` 或者 `Retain`。如果 `StorageClass` 对象被创建时没有指定 `reclaimPolicy` ,它将默认为 `Delete`。 + +通过 `StorageClass` 手动创建并管理的 Persistent Volume 会使用它们被创建时指定的回收政策。 + + +### 挂载选项 + +由 `StorageClass` 动态创建的 Persistent Volume 将使用`类`中 `mountOption` 字段指定的挂载选项。 + +如果卷插件不支持挂载选项,却指定了该选项,则分配操作会失败。 +挂载选项在 `StorageClass` 和持久卷上都不会做验证,所以如果挂载选项无效,那么这个 PV 就会失败。 + + +### 卷绑定模式 + +{{< feature-state for_k8s_version="v1.12" state="beta" >}} + + +**注意:** 这个功能特性需要启用 `VolumeScheduling` 参数才能使用。 + + +`volumeBindingMode` 字段控制了 [卷绑定和动态分配](/docs/concepts/storage/persistent-volumes/#provisioning) +应该发生在什么时候。 + + +默认情况下,`Immediate` 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态分配。 +对于由于拓扑限制而非集群所有节点可达的存储后端,PersistentVolume 会在不知道 Pod 调度要求的情况下绑定或者分配。 + + +集群管理员可以通过指定 `WaitForFirstConsumer` 模式来解决此问题。 +该模式将延迟 PersistentVolume 的绑定和分配,直到使用该 PersistentVolumeClaim 的 Pod 被创建。 +PersistentVolume 会根据 Pod 调度约束指定的拓扑来选择或分配。这些包括但不限于 [资源需求](/docs/concepts/configuration/manage-compute-resources-container), +[节点筛选器](/docs/concepts/configuration/assign-pod-node/#nodeselector), +[pod 亲和性和互斥性](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity), +以及 [污点和容忍度](/docs/concepts/configuration/taint-and-toleration). + + +以下插件支持动态分配的 `WaitForFirstConsumer` 模式: + +* [AWSElasticBlockStore](#aws-ebs) +* [GCEPersistentDisk](#gce-pd) +* [AzureDisk](#azure-disk) + + +以下插件支持预创建绑定 PersistentVolume 的 `WaitForFirstConsumer` 模式: + +* All of the above +* [Local](#local) + + +### 允许的拓扑结构 +{{< feature-state for_k8s_version="v1.12" state="beta" >}} + + +**注意:** 这个特性需要开启 `VolumeScheduling` 特性开关。 + + +当集群操作人员使用了 `WaitForFirstConsumer` 的卷绑定模式,在大部分情况下就没有必要将配置限制为特定的拓扑结构。 +然而,如果还有需要的话,可以使用 `allowedTopologies`。 + + +这个例子描述了如何将分配卷限的拓扑限制在特定的区域,在使用时应该根据插件支持情况替换 `zone` 和 `zones` 参数。 + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: standard +provisioner: kubernetes.io/gce-pd +parameters: + type: pd-standard +volumeBindingMode: WaitForFirstConsumer +allowedTopologies: +- matchLabelExpressions: + - key: failure-domain.beta.kubernetes.io/zone + values: + - us-central1-a + - us-central1-b +``` + + +## 参数 + +Storage class 具有描述属于卷的参数。取决于分配器,可以接受不同的参数。 +例如,参数 type 的值 io1 和参数 iopsPerGB 特定于 EBS PV。当参数被省略时,会使用默认值。 + +### AWS EBS + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: slow +provisioner: kubernetes.io/aws-ebs +parameters: + type: io1 + iopsPerGB: "10" + fsType: ext4 +``` + + +* `type`:`io1`,`gp2`,`sc1`,`st1`。详细信息参见 [AWS 文档](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)。默认值:`gp2`。 +* `zone`(弃用):AWS 区域。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone` 和 `zones` 参数不能同时使用。 +* `zones`(弃用):以逗号分隔的 AWS 区域列表。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone`和`zones`参数不能同时使用。 +* `iopsPerGB`:只适用于 `io1` 卷。每 GiB 每秒 I/O 操作。AWS 卷插件将其与请求卷的大小相乘以计算 IOPS 的容量,并将其限制在 20 000 IOPS(AWS 支持的最高值,请参阅 [AWS 文档](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)。 + 这里需要输入一个字符串,即 `"10"`,而不是 `10`。 +* `fsType`:受 Kubernetes 支持的文件类型。默认值:`"ext4"`。 +* `encrypted`:指定 EBS 卷是否应该被加密。合法值为 `"true"` 或者 `"false"`。这里需要输入字符串,即 `"true"`, 而非 `true`。 +* `kmsKeyId`:可选。加密卷时使用密钥的完整 Amazon 资源名称。如果没有提供,但 `encrypted` 值为 true,AWS 生成一个密钥。关于有效的 ARN 值,请参阅 AWS 文档。 + +**注意:** `zone` 和 `zones` 已被弃用并被 [允许的拓扑结构](#allowed-topologies) 取代。 + +### GCE PD + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: slow +provisioner: kubernetes.io/gce-pd +parameters: + type: pd-standard + replication-type: none +``` + +* `type`:`pd-standard` 或者 `pd-ssd`。默认:`pd-standard` +* `zone`(弃用):GCE 区域。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone` 和 `zones` 参数不能同时使用。 +* `zones`(弃用):逗号分隔的 GCE 区域列表。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度(round-robin)分配。`zone` 和 `zones` 参数不能同时使用。 +* `replication-type`:`none` 或者 `regional-pd`。默认值:`none`。 + + +如果 `replication-type` 设置为 `none`,会分配一个常规(当前区域内的)持久化磁盘。 + + +如果 `replication-type` 设置为 `regional-pd`,会分配一个 [区域性持久化磁盘(Regional Persistent Disk)](https://cloud.google.com/compute/docs/disks/#repds)。在这种情况下,用户必须使用 `zones` 而非 `zone` 来指定期望的复制区域(zone)。如果指定来两个特定的区域,区域性持久化磁盘会在这两个区域里分配。如果指定了多于两个的区域,Kubernetes 会选择其中任意两个区域。如果省略了 `zones` 参数,Kubernetes 会在集群管理的区域中任意选择。 + + +**注意:** `zone` 和 `zones` 已被弃用并被 [allowedTopologies](#allowed-topologies) 取代。 + +### Glusterfs + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: slow +provisioner: kubernetes.io/glusterfs +parameters: + resturl: "http://127.0.0.1:8081" + clusterid: "630372ccdc720a92c681fb928f27b53f" + restauthenabled: "true" + restuser: "admin" + secretNamespace: "default" + secretName: "heketi-secret" + gidMin: "40000" + gidMax: "50000" + volumetype: "replicate:3" +``` + + +* `resturl`:分配 gluster 卷的需求的 Gluster REST 服务/Heketi 服务 url。 + 通用格式应该是 `IPaddress:Port`,这是 GlusterFS 动态分配器的必需参数。 + 如果 Heketi 服务在 openshift/kubernetes 中安装并暴露为可路由服务,则可以使用类似于 + `http://heketi-storage-project.cloudapps.mystorage.com` 的格式,其中 fqdn 是可解析的 heketi 服务网址。 +* `restauthenabled`:Gluster REST 服务身份验证布尔值,用于启用对 REST 服务器的身份验证。如果此值为 'true',则必须填写 `restuser` 和 `restuserkey` 或 `secretNamespace` + `secretName`。此选项已弃用,当在指定 `restuser`,`restuserkey`,`secretName` 或 `secretNamespace` 时,身份验证被启用。 +* `restuser`:在 Gluster 可信池中有权创建卷的 Gluster REST服务/Heketi 用户。 +* `restuserkey`:Gluster REST 服务/Heketi 用户的密码将被用于对 REST 服务器进行身份验证。此参数已弃用,取而代之的是 `secretNamespace` + `secretName`。 + +* `secretNamespace`,`secretName`:Secret 实例的标识,包含与 Gluster REST 服务交互时使用的用户密码。 + 这些参数是可选的,`secretNamespace` 和 `secretName` 都省略时使用空密码。所提供的 Secret 必须将类型设置为 "kubernetes.io/glusterfs",例如以这种方式创建: + + ``` + kubectl create secret generic heketi-secret \ + --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' \ + --namespace=default + ``` + + secret 的例子可以在 [glusterfs-provisioning-secret.yaml](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml) 中找到。 + +* `clusterid`:`630372ccdc720a92c681fb928f27b53f` 是集群的 ID,当分配卷时,Heketi 将会使用这个文件。它也可以是一个 clusterid 列表,例如: + `"8452344e2becec931ece4e33c4674e4e,42982310de6c63381718ccfa6d8cf397"`。这个是可选参数。 +* `gidMin`,`gidMax`:storage class GID 范围的最小值和最大值。在此范围(gidMin-gidMax)内的唯一值(GID)将用于动态分配卷。这些是可选的值。如果不指定,卷将被分配一个 2000-2147483647 之间的值,这是 gidMin 和 gidMax 的默认值。 + +* `volumetype`:卷的类型及其参数可以用这个可选值进行配置。如果未声明卷类型,则由分配器决定卷的类型。 + + 例如: + 'Replica volume': `volumetype: replicate:3` 其中 '3' 是 replica 数量. + 'Disperse/EC volume': `volumetype: disperse:4:2` 其中 '4' 是数据,'2' 是冗余数量. + 'Distribute volume': `volumetype: none` + + 有关可用的卷类型和管理选项,请参阅 [管理指南](https://access.redhat.com/documentation/en-US/Red_Hat_Storage/3.1/html/Administration_Guide/part-Overview.html)。 + + 更多相关的参考信息,请参阅 [如何配置 Heketi](https://github.com/heketi/heketi/wiki/Setting-up-the-topology)。 + + 当动态分配持久卷时,Gluster 插件自动创建名为 `gluster-dynamic-` 的端点和 headless service。在 PVC 被删除时动态端点和 headless service 会自动被删除。 + +### OpenStack Cinder + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: gold +provisioner: kubernetes.io/cinder +parameters: + availability: nova +``` + + +* `availability`:可用区域。如果没有指定,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。 + + +{{< note >}} +{{< feature-state state="deprecated" for_k8s_version="1.11" >}} +OpenStack 的内部驱动程序已经被弃用。请使用 [OpenStack 的外部驱动程序](https://github.com/kubernetes/cloud-provider-openstack)。 +{{< /note >}} + +### vSphere + + +1. 使用用户指定的磁盘格式创建一个 StorageClass。 + + ```yaml + kind: StorageClass + apiVersion: storage.k8s.io/v1 + metadata: + name: fast + provisioner: kubernetes.io/vsphere-volume + parameters: + diskformat: zeroedthick + ``` + + + `diskformat`: `thin`, `zeroedthick` 和 `eagerzeroedthick`。默认值: `"thin"`。 + + +2. 在用户指定的数据存储上创建磁盘格式的 StorageClass。 + + ```yaml + kind: StorageClass + apiVersion: storage.k8s.io/v1 + metadata: + name: fast + provisioner: kubernetes.io/vsphere-volume + parameters: + diskformat: zeroedthick + datastore: VSANDatastore + ``` + + + `datastore`:用户也可以在 StorageClass 中指定数据存储。卷将在 storage class 中指定的数据存储上创建,在这种情况下是 `VSANDatastore`。该字段是可选的。如果未指定数据存储,则将在用于初始化 vSphere Cloud Provider 的 vSphere 配置文件中指定的数据存储上创建该卷。 + + +3. Kubernetes 中的存储策略管理 + + + * 使用现有的 vCenter SPBM 策略 + + vSphere 用于存储管理的最重要特性之一是基于策略的管理。基于存储策略的管理(SPBM)是一个存储策略框架,提供单一的统一控制平面的跨越广泛的数据服务和存储解决方案。 SPBM 使能 vSphere 管理员克服先期的存储配置挑战,如容量规划,差异化服务等级和管理容量空间。 + + SPBM 策略可以在 StorageClass 中使用 `storagePolicyName` 参数声明。 + + + * Kubernetes 内的 Virtual SAN 策略支持 + + Vsphere Infrastructure(VI)管理员将能够在动态卷配置期间指定自定义 Virtual SAN 存储功能。您现在可以定义存储需求,例如性能和可用性,当动态卷供分配时会以存储功能的形式提供。存储功能需求会转换为 Virtual SAN 策略,然后当 persistent volume(虚拟磁盘)在创建时,会将其推送到 Virtual SAN 层。虚拟磁盘分布在 Virtual SAN 数据存储中以满足要求。 + + 更多有关 persistent volume 管理的存储策略的详细信息, + 您可以参考 [基于存储策略的动态分配卷管理](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/policy-based-mgmt.html)。 + + +有几个 [vSphere 例子](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere) +供您在 Kubernetes for vSphere 中尝试进行 persistent volume 管理。 + +### Ceph RBD + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast +provisioner: kubernetes.io/rbd +parameters: + monitors: 10.16.153.105:6789 + adminId: kube + adminSecretName: ceph-secret + adminSecretNamespace: kube-system + pool: kube + userId: kube + userSecretName: ceph-secret-user + userSecretNamespace: default + fsType: ext4 + imageFormat: "2" + imageFeatures: "layering" +``` + + +* `monitors`:Ceph monitor,逗号分隔。该参数是必需的。 +* `adminId`:Ceph 客户端 ID,用于在池 ceph 池中创建映像。默认是 "admin"。 +* `adminSecret`:`adminId` 的 Secret 名称。该参数是必需的。 + 提供的 secret 必须有值为 "kubernetes.io/rbd" 的 type 参数。 +* `adminSecretNamespace`:`adminSecret` 的命名空间。默认是 "default"。 +* `pool`: Ceph RBD 池. 默认是 "rbd"。 +* `userId`:Ceph 客户端 ID,用于映射 RBD 镜像。默认与 `adminId` 相同。 + +* `userSecretName`:用于映射 RBD 镜像的 `userId` 的 Ceph Secret 的名字。 + 它必须与 PVC 存在于相同的 namespace 中。该参数是必需的。 + 提供的 secret 必须具有值为 "kubernetes.io/rbd" 的 type 参数,例如以这样的方式创建: + + ```shell + kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ + --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ + --namespace=kube-system + ``` + + +* `userSecretNamespace`:`userSecretName` 的命名空间。 +* `fsType`:Kubernetes 支持的 fsType。默认:`"ext4"`。 +* `imageFormat`:Ceph RBD 镜像格式,"1" 或者 "2"。默认值是 "1"。 +* `imageFeatures`:这个参数是可选的,只能在你将 `imageFormat` 设置为 "2" 才使用。 + 目前支持的功能只是 `layering`。默认是 "",没有功能打开。 + +### Quobyte + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: slow +provisioner: kubernetes.io/quobyte +parameters: + quobyteAPIServer: "http://138.68.74.142:7860" + registry: "138.68.74.142:7861" + adminSecretName: "quobyte-admin-secret" + adminSecretNamespace: "kube-system" + user: "root" + group: "root" + quobyteConfig: "BASE" + quobyteTenant: "DEFAULT" +``` + + +* `quobyteAPIServer`:Quobyte API 服务器的格式是 + `"http(s)://api-server:7860"` +* `registry`:用于挂载卷的 Quobyte registry。你可以指定 registry 为 ``:`` + 或者如果你想指定多个 registry,你只需要在他们之间添加逗号,例如 + ``:,:,:``。 + 主机可以是一个 IP 地址,或者如果您有正在运行的 DNS,您也可以提供 DNS 名称。 +* `adminSecretNamespace`:`adminSecretName`的 namespace。 + 默认值是 "default"。 + +* `adminSecretName`:保存关于 Quobyte 用户和密码的 secret,用于对 API 服务器进行身份验证。 + 提供的 secret 必须有值为 "kubernetes.io/quobyte" 的 type 参数,例如以这种方式创建: + + ```shell + kubectl create secret generic quobyte-admin-secret \ + --type="kubernetes.io/quobyte" --from-literal=key='opensesame' \ + --namespace=kube-system + ``` + +* `user`:对这个用户映射的所有访问权限。默认是 "root"。 +* `group`:对这个组映射的所有访问权限。默认是 "nfsnobody"。 +* `quobyteConfig`:使用指定的配置来创建卷。您可以创建一个新的配置,或者,可以修改 Web console 或 + quobyte CLI 中现有的配置。默认是 "BASE"。 +* `quobyteTenant`:使用指定的租户 ID 创建/删除卷。这个 Quobyte 租户必须已经于 Quobyte。 + 默认是 "DEFAULT"。 + + +### Azure 磁盘 + + +#### Azure Unmanaged Disk Storage Class(非托管磁盘存储类) + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: slow +provisioner: kubernetes.io/azure-disk +parameters: + skuName: Standard_LRS + location: eastus + storageAccount: azure_storage_account_name +``` + + +* `skuName`:Azure 存储帐户 Sku 层。默认为空。 +* `location`:Azure 存储帐户位置。默认为空。 +* `storageAccount`:Azure 存储帐户名称。如果提供存储帐户,它必须位于与集群相同的资源组中,并且 `location` 是被忽略的。如果未提供存储帐户,则会在与群集相同的资源组中创建新的存储帐户。 + + +#### 新的 Azure 磁盘 Storage Class(从 v1.7.2 开始) + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: slow +provisioner: kubernetes.io/azure-disk +parameters: + storageaccounttype: Standard_LRS + kind: Shared +``` + + +* `storageaccounttype`:Azure 存储帐户 Sku 层。默认为空。 +* `kind`:可能的值是 `shared`(默认)、`dedicated` 和 `managed`。 + 当 `kind` 的值是 `shared` 时,所有非托管磁盘都在集群的同一个资源组中的几个共享存储帐户中创建。 + 当 `kind` 的值是 `dedicated` 时,将为在集群的同一个资源组中新的非托管磁盘创建新的专用存储帐户。 + + +- Premium VM 可以同时添加 Standard_LRS 和 Premium_LRS 磁盘,而 Standard 虚拟机只能添加 Standard_LRS 磁盘。 +- 托管虚拟机只能连接托管磁盘,非托管虚拟机只能连接非托管磁盘。 + + +### Azure 文件 + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: azurefile +provisioner: kubernetes.io/azure-file +parameters: + skuName: Standard_LRS + location: eastus + storageAccount: azure_storage_account_name +``` + + +* `skuName`:Azure 存储帐户 Sku 层。默认为空。 +* `location`:Azure 存储帐户位置。默认为空。 +* `storageAccount`:Azure 存储帐户名称。默认为空。 + 如果不提供存储帐户,会搜索所有与资源相关的存储帐户,以找到一个匹配 `skuName` 和 `location` 的账号。 + 如果提供存储帐户,它必须存在于与集群相同的资源组中,`skuName` 和 `location` 会被忽略。 + + +在分配期间,为挂载凭证创建一个 secret。如果集群同时启用了 [RBAC](/docs/admin/authorization/rbac/) 和 [Controller Roles](/docs/admin/authorization/rbac/#controller-roles), +为 `system:controller:persistent-volume-binder` 的 clusterrole 添加 `secret` 资源的 `create` 权限。 + + +### Portworx 卷 + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: portworx-io-priority-high +provisioner: kubernetes.io/portworx-volume +parameters: + repl: "1" + snap_interval: "70" + io_priority: "high" + +``` + + +* `fs`:选择的文件系统:[none/xfs/ext4](默认:`ext4`)。 +* `block_size`:以 Kbytes 为单位的块大小(默认值:`32`)。 +* `repl`:同步副本数量,以复制因子 [1..3](默认值:`1`)的形式提供。 + 这里需要填写字符串,即,`"1"` 而不是 `1`。 +* `io_priority`:决定是否从更高性能或者较低优先级存储创建卷 [high/medium/low](默认值:`low`)。 +* `snap_interval`:触发快照的时钟/时间间隔(分钟)。快照是基于与先前快照的增量变化,0 是禁用快照(默认:`0`)。 + 这里需要填写字符串,即,是 `"70"` 而不是 `70`。 +* `aggregation_level`:指定卷分配到的块数量,0 表示一个非聚合卷(默认:`0`)。 + 这里需要填写字符串,即,是 `"0"` 而不是 `0`。 +* `ephemeral`:指定卷在卸载后进行清理还是持久化。 `emptyDir` 的使用场景可以将这个值设置为 true , + `persistent volumes` 的使用场景可以将这个值设置为 false(例如 Cassandra 这样的数据库)[true/false](默认为 `false`)。这里需要填写字符串,即,是 `"true"` 而不是 `true`。 + +### ScaleIO + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: slow +provisioner: kubernetes.io/scaleio +parameters: + gateway: https://192.168.99.200:443/api + system: scaleio + protectionDomain: pd0 + storagePool: sp1 + storageMode: ThinProvisioned + secretRef: sio-secret + readOnly: false + fsType: xfs +``` + + +* `provisioner`:属性设置为 `kubernetes.io/scaleio` +* `gateway` 到 ScaleIO API 网关的地址(必需) +* `system`:ScaleIO 系统的名称(必需) +* `protectionDomain`:ScaleIO 保护域的名称(必需) +* `storagePool`:卷存储池的名称(必需) +* `storageMode`:存储提供模式:`ThinProvisioned`(默认)或 `ThickProvisioned` +* `secretRef`:对已配置的 Secret 对象的引用(必需) +* `readOnly`:指定挂载卷的访问模式(默认为 false) +* `fsType`:卷的文件系统(默认是 ext4) + + +ScaleIO Kubernetes 卷插件需要配置一个 Secret 对象。 +secret 必须用 `kubernetes.io/scaleio` 类型创建,并与引用它的 PVC 所属的名称空间使用相同的值 +如下面的命令所示: + +```shell +kubectl create secret generic sio-secret --type="kubernetes.io/scaleio" \ +--from-literal=username=sioadmin --from-literal=password=d2NABDNjMA== \ +--namespace=default +``` + +### StorageOS + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast +provisioner: kubernetes.io/storageos +parameters: + pool: default + description: Kubernetes volume + fsType: ext4 + adminSecretNamespace: default + adminSecretName: storageos-secret +``` + + +* `pool`:分配卷的 StorageOS 分布式容量池的名称。如果未指定,则使用通常存在的 `default` 池。 +* `description`:分配给动态创建的卷的描述。所有卷描述对于 storage class 都是相同的, + 但不同的 storage class 可以使用不同的描述,以区分不同的使用场景。 + 默认为 `Kubernetas volume`。 +* `fsType`:请求的默认文件系统类型。请注意,在 StorageOS 中用户定义的规则可以覆盖此值。默认为 `ext4` +* `adminSecretNamespace`:API 配置 secret 所在的命名空间。如果设置了 adminSecretName,则是必需的。 +* `adminSecretName`:用于获取 StorageOS API 凭证的 secret 名称。如果未指定,则将尝试默认值。 + + +StorageOS Kubernetes 卷插件可以使 Secret 对象来指定用于访问 StorageOS API 的端点和凭据。 +只有当默认值已被更改时,这才是必须的。 +secret 必须使用 `kubernetes.io/storageos` 类型创建,如以下命令: + +```shell +kubectl create secret generic storageos-secret \ +--type="kubernetes.io/storageos" \ +--from-literal=apiAddress=tcp://localhost:5705 \ +--from-literal=apiUsername=storageos \ +--from-literal=apiPassword=storageos \ +--namespace=default +``` + + +用于动态分配卷的 Secret 可以在任何名称空间中创建,并通过 `adminSecretNamespace` 参数引用。 +预先配置的卷使用的 Secret 必须在与引用它的 PVC 在相同的名称空间中。 + + +### 本地 + +{{< feature-state for_k8s_version="v1.10" state="beta" >}} + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: local-storage +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: WaitForFirstConsumer +``` + + +本地卷还不支持动态分配,然而还是需要创建 StorageClass 以延迟卷绑定,直到完成 pod 的调度。这是由 `WaitForFirstConsumer` 卷绑定模式指定的。 + + +延迟卷绑定使得调度器在为 PersistentVolumeClaim 选择一个合适的 PersistentVolume 时能考虑到所有 pod 的调度限制。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/storage/storage-limits.md b/content/zh/docs/concepts/storage/storage-limits.md new file mode 100644 index 0000000000000..832c6b5c9ed00 --- /dev/null +++ b/content/zh/docs/concepts/storage/storage-limits.md @@ -0,0 +1,140 @@ +--- +title: 特定于节点的卷数限制 +content_template: templates/concept +--- + + + +{{% capture overview %}} + + +此页面描述了各个云供应商可关联至一个节点的最大卷数。 + + + +谷歌、亚马逊和微软等云供应商通常对可以关联到节点的卷数量进行限制。 +Kubernetes 需要尊重这些限制。 否则,在节点上调度的 Pod 可能会卡住去等待卷的关联。 + + + +{{% /capture %}} + +{{% capture body %}} + + + +## Kubernetes 的默认限制 + +The Kubernetes 调度器对关联于一个节点的卷数有默认限制: + + + + + + +
云服务每节点最大卷数
Amazon Elastic Block Store (EBS)39
Google Persistent Disk16
Microsoft Azure Disk Storage16
+ + + +## 自定义限制 + +您可以通过设置 `KUBE_MAX_PD_VOLS` 环境变量的值来设置这些限制,然后再启动调度器。 + +如果设置的限制高于默认限制,请谨慎使用。请参阅云提供商的文档以确保节点可支持您设置的限制。 + +此限制应用于整个集群,所以它会影响所有节点。 + + + +## 动态卷限制 + +{{< feature-state state="beta" for_k8s_version="v1.12" >}} + + + +Kubernetes 1.11 引入了基于节点类型的动态卷限制的支持作为 Alpha 功能。 +在 Kubernetes 1.12 中,此功能升级到 Beta 版,将默认开启。 + +以下卷类型支持动态卷限制。 + +- Amazon EBS +- Google Persistent Disk +- Azure Disk +- CSI + + + +启用动态卷限制功能后,Kubernetes 会自动确定节点类型并确保节点上可关联的卷数目合规。 例如: + + + +* 在 +Google Compute Engine环境中, +[根据节点类型](https://cloud.google.com/compute/docs/disks/#pdnumberlimits)最多可以将128个卷关联到节点。 + +* 对于 M5、C5、R5、T3 和 Z1D 类型实例的 Amazon EBS 磁盘,Kubernetes 仅允许 25 个卷关联到节点。 +对于 ec2 上的其他实例类型 +Amazon Elastic Compute Cloud (EC2), +Kubernetes 允许 39 个卷关联至节点。 + +* 在 Azure 环境中, 根据节点类型,最多 64 个磁盘可以关联至一个节点。 +更多详细信息,请参阅[Azure 虚拟机的数量大小](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes)。 + +* 对于 CSI,任何符合 CSI 规范中卷关联限制的驱动都将这些限制作为 Node 的 allocatable 属性。调度器不会往已经达到其容量限制的任何节点上调度具有卷的Pod。 参考 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#nodegetinfo) 获取更多详细信息。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/storage/volume-snapshot-classes.md b/content/zh/docs/concepts/storage/volume-snapshot-classes.md new file mode 100644 index 0000000000000..17ea4de4134e6 --- /dev/null +++ b/content/zh/docs/concepts/storage/volume-snapshot-classes.md @@ -0,0 +1,84 @@ +--- +title: 卷快照类 +content_template: templates/concept +weight: 30 +--- + +{{% capture overview %}} + + + + +本文档描述了 Kubernetes 中 `VolumeSnapshotClass` 的概念。 建议熟悉[卷快照(Volume Snapshots)](/docs/concepts/storage/volume-snapshots/)和[存储类(Storage Class)](/docs/concepts/storage/storage-classes)。 +{{% /capture %}} + + +{{% capture body %}} + + + +## 介绍 + +就像 `StorageClass` 为管理员提供了一种在配置卷时描述存储“类”的方法,`VolumeSnapshotClass` 提供了一种在配置卷快照时描述存储“类”的方法。 + + + +## VolumeSnapshotClass 资源 + +每个 `VolumeSnapshotClass` 都包含 `snapshotter` 和 `parameters` 字段,当需要动态配置属于该类的 `VolumeSnapshot` 时使用。 + +`VolumeSnapshotClass` 对象的名称很重要,是用户可以请求特定类的方式。 +管理员在首次创建 `VolumeSnapshotClass` 对象时设置类的名称和其他参数,对象一旦创建就无法更新。 + +管理员可以为不请求任何特定类绑定的 VolumeSnapshots 指定默认的 `VolumeSnapshotClass`。 + + +```yaml +apiVersion: snapshot.storage.k8s.io/v1alpha1 +kind: VolumeSnapshotClass +metadata: + name: csi-hostpath-snapclass +snapshotter: csi-hostpath +parameters: +``` + + +### 快照生成器(Snapshotter) + +卷快照类具有一个快照生成器,用于确定配置 VolumeSnapshot 的 CSI 卷插件。 必须指定此字段。 + + + +## 参数 + +卷快照类具有描述属于卷快照类的卷快照参数。 可根据 `snapshotter` 接受不同的参数。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/storage/volumes.md b/content/zh/docs/concepts/storage/volumes.md new file mode 100644 index 0000000000000..7288ac10a1b0e --- /dev/null +++ b/content/zh/docs/concepts/storage/volumes.md @@ -0,0 +1,2093 @@ +--- +reviewers: +- jsafrane +- saad-ali +- thockin +- msau42 +title: Volumes +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} + + + +容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题。 +首先,当容器崩溃时,kubelet 将重新启动容器,容器中的文件将会丢失——因为容器会以干净的状态重建。 +其次,当在一个 `Pod` 中同时运行多个容器时,常常需要在这些容器之间共享文件。 +Kubernetes 抽象出 `Volume` 对象来解决这两个问题。 + + + +阅读本文前建议您熟悉一下 [Pods](/docs/user-guide/pods)。 + +{{% /capture %}} + + +{{% capture body %}} + + + +## 背景 + +Docker 也有 [Volume](https://docs.docker.com/engine/admin/volumes/) 的概念,但对它只有少量且松散的管理。 +在 Docker 中,Volume 是磁盘上或者另外一个容器内的一个目录。 +直到最近,Docker 才支持对基于本地磁盘的 Volume 的生存期进行管理。 +虽然 Docker 现在也能提供 Volume 驱动程序,但是目前功能还非常有限(例如,截至 Docker 1.7,每个容器只允许有一个 Volume 驱动程序,并且无法将参数传递给卷)。 + + + +另一方面,Kubernetes 卷具有明确的生命周期——与包裹它的 Pod 相同。 +因此,卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留。 +当然,当一个 Pod 不再存在时,卷也将不再存在。也许更重要的是,Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。 + + + +卷的核心是包含一些数据的目录,Pod 中的容器可以访问该目录。 +特定的卷类型可以决定这个目录如何形成的,并能决定它支持何种介质,以及目录中存放什么内容。 + + + + +使用卷时, Pod 声明中需要提供卷的类型 (`.spec.volumes` 字段)和卷挂载的位置 (`.spec.containers.volumeMounts` 字段). + + + +容器中的进程能看到由它们的 Docker 镜像和卷组成的文件系统视图。 +[Docker 镜像](https://docs.docker.com/userguide/dockerimages/) 位于文件系统层次结构的根部,并且任何 Volume 都挂载在镜像内的指定路径上。 +卷不能挂载到其他卷,也不能与其他卷有硬链接。 +Pod 中的每个容器必须独立地指定每个卷的挂载位置。 + + + +## Volume 的类型 + +Kubernetes 支持下列类型的卷: + + + * [awsElasticBlockStore](#awselasticblockstore) + * [azureDisk](#azuredisk) + * [azureFile](#azurefile) + * [cephfs](#cephfs) + * [configMap](#configmap) + * [csi](#csi) + * [downwardAPI](#downwardapi) + * [emptyDir](#emptydir) + * [fc (fibre channel)](#fc) + * [flocker](#flocker) + * [gcePersistentDisk](#gcepersistentdisk) + * [gitRepo (deprecated)](#gitrepo) + * [glusterfs](#glusterfs) + * [hostPath](#hostpath) + * [iscsi](#iscsi) + * [local](#local) + * [nfs](#nfs) + * [persistentVolumeClaim](#persistentvolumeclaim) + * [projected](#projected) + * [portworxVolume](#portworxvolume) + * [quobyte](#quobyte) + * [rbd](#rbd) + * [scaleIO](#scaleio) + * [secret](#secret) + * [storageos](#storageos) + * [vsphereVolume](#vspherevolume) + + + +我们欢迎大家贡献其他的卷类型支持。 + +### awsElasticBlockStore {#awselasticblockstore} + + + +`awsElasticBlockStore` 卷将 Amazon Web服务(AWS)[EBS 卷](http://aws.amazon.com/ebs/) 挂载到您的 Pod 中。 +与 `emptyDir` 在删除 Pod 时会被删除不同,EBS 卷的内容在删除 Pod 时会被保留,卷只是被卸载掉了。 +这意味着 EBS 卷可以预先填充数据,并且可以在 Pod 之间传递数据。 + +{{< caution >}} + +您在使用 EBS 卷之前必须先创建它,可以使用 `aws ec2 create-volume` 命令进行创建;也可以使用 AWS API 进行创建。 +{{< /caution >}} + + + +使用 `awsElasticBlockStore` 卷时有一些限制: + +* Pod 正在运行的节点必须是 AWS EC2 实例。 +* 这些实例需要与 EBS 卷在相同的地域(region)和可用区(availability-zone)。 +* EBS 卷只支持被挂载到单个 EC2 实例上。 + + + +#### 创建 EBS 卷 + +在将 EBS 卷用到 Pod 上之前,您首先要创建它。 + +```shell +aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2 +``` + + + +确保该区域与您的群集所在的区域相匹配。(也要检查卷的大小和 EBS 卷类型都适合您的用途!) + + + +#### AWS EBS 配置示例 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-ebs +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /test-ebs + name: test-volume + volumes: + - name: test-volume + # This AWS EBS volume must already exist. + awsElasticBlockStore: + volumeID: + fsType: ext4 +``` + +### azureDisk {#azuredisk} + + + +`azureDisk` 用来在 Pod 上挂载 Microsoft Azure [数据盘(Data Disk)](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-about-disks-vhds/) . +更多详情请参考[这里](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/azure_disk/README.md)。 + +### azureFile {#azurefile} + + + +`azureFile` 用来在 Pod 上挂载 Microsoft Azure 文件卷(File Volume) (SMB 2.1 和 3.0)。 +更多详情请参考[这里](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/azure_file/README.md)。 + +### cephfs {#cephfs} + + + +`cephfs` 允许您将现存的 CephFS 卷挂载到 Pod 中。不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`cephfs` 卷的内容在删除 Pod 时会被保留,卷只是被卸载掉了。 +这意味着 CephFS 卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。CephFS 卷可同时被多个写者挂载。 + + +{{< caution >}} + +在您使用 Ceph 卷之前,您的 Ceph 服务器必须正常运行并且要使用的 share 被导出(exported)。 +{{< /caution >}} + + + +更多信息请参考 [CephFS 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/cephfs/)。 + +### configMap {#configmap} + + + +[`configMap`](/docs/tasks/configure-pod-container/configure-pod-configmap/) 资源提供了向 Pod 注入配置数据的方法。 +`ConfigMap` 对象中存储的数据可以被 `configMap` 类型的卷引用,然后被应用到 Pod 中运行的容器化应用。 + + + +当引用 `configMap` 对象时,你可以简单的在 Volume 中通过它名称来引用。 +还可以自定义 ConfigMap 中特定条目所要使用的路径。 +例如,要将名为 `log-config` 的 ConfigMap 挂载到名为 `configmap-pod` 的 Pod 中,您可以使用下面的 YAML: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod +spec: + containers: + - name: test + image: busybox + volumeMounts: + - name: config-vol + mountPath: /etc/config + volumes: + - name: config-vol + configMap: + name: log-config + items: + - key: log_level + path: log_level +``` + + + +`log-config` ConfigMap 是以卷的形式挂载的, +存储在 `log_level` 条目中的所有内容都被挂载到 Pod 的 "`/etc/config/log_level`" 路径下。 +请注意,这个路径来源于 Volume 的 `mountPath` 和 `log_level` 键对应的 `path`。 + +{{< caution >}} + +在使用 [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/) 之前您首先要创建它。 +{{< /caution >}} + +{{< note >}} + +容器以 [subPath](#using-subpath) 卷挂载方式使用 ConfigMap 时,将无法接收 ConfigMap 的更新。 +{{< /note >}} + +### downwardAPI {#downwardapi} + + + +`downwardAPI` 卷用于使 downward API 数据对应用程序可用。 +这种卷类型挂载一个目录并在纯文本文件中写入请求的数据。 + +{{< note >}} + +容器以挂载 [subPath](#using-subpath) 卷的方式使用 downwardAPI 时,将不能接收到它的更新。 +{{< /note >}} + + +更多详细信息请参考 [`downwardAPI` 卷示例](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/)。 + +### emptyDir {#emptydir} + + + +当 Pod 指定到某个节点上时,首先创建的是一个 `emptyDir` 卷,并且只要 Pod 在该节点上运行,卷就一直存在。 +就像它的名称表示的那样,卷最初是空的。 +尽管 Pod 中的容器挂载 `emptyDir` 卷的路径可能相同也可能不同,但是这些容器都可以读写 `emptyDir` 卷中相同的文件。 +当 Pod 因为某些原因被从节点上删除时,`emptyDir` 卷中的数据也会永久删除。 + +{{< note >}} + +容器崩溃并不会导致 Pod 被从节点上移除,因此容器崩溃时 `emptyDir` 卷中的数据是安全的。 +{{< /note >}} + + + +`emptyDir` 的一些用途: + +* 缓存空间,例如基于磁盘的归并排序。 +* 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。 +* 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。 + + + + +默认情况下, `emptyDir` 卷存储在支持该节点所使用的介质上;这里的介质可以是磁盘或 SSD 或网络存储,这取决于您的环境。 +但是,您可以将 `emptyDir.medium` 字段设置为 `"Memory"`,以告诉 Kubernetes 为您安装 tmpfs(基于 RAM 的文件系统)。 +虽然 tmpfs 速度非常快,但是要注意它与磁盘不同。 +tmpfs 在节点重启时会被清除,并且您所写入的所有文件都会计入容器的内存消耗,受容器内存限制约束。 + + + +#### Pod 示例 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-pd +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /cache + name: cache-volume + volumes: + - name: cache-volume + emptyDir: {} +``` + + + +### fc (光纤通道) {#fc} + +`fc` 卷允许将现有的光纤通道卷挂载到 Pod 中。 +可以使用卷配置中的参数 `targetWWNs` 来指定单个或多个目标 WWN。 +如果指定多个 WWN,targetWWNs 期望这些 WWN 来自多路径连接。 + +{{< caution >}} + +您必须配置 FC SAN Zoning,以便预先向目标 WWN 分配和屏蔽这些 LUN(卷),这样 Kubernetes 主机才可以访问它们。 +{{< /caution >}} + + + +更多详情请参考 [FC 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/fibre_channel)。 + + + +### flocker {#flocker} + +[Flocker](https://github.com/ClusterHQ/flocker) 是一个开源的、集群化的容器数据卷管理器。 +Flocker 提供了由各种存储后备支持的数据卷的管理和编排。 + + + +`flocker` 卷允许将一个 Flocker 数据集挂载到 Pod 中。 +如果数据集在 Flocker 中不存在,则需要首先使用 Flocker CLI 或 Flocker API 创建数据集。 +如果数据集已经存在,那么 Flocker 将把它重新附加到 Pod 被调度的节点。 +这意味着数据可以根据需要在 Pod 之间 "传递"。 + + +{{< caution >}} + +您在使用 Flocker 之前必须先安装运行自己的 Flocker。 +{{< /caution >}} + + + +更多详情请参考 [Flocker 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/flocker)。 + + + +### gcePersistentDisk {#gcepersistentdisk} + +`gcePersistentDisk` 卷能将谷歌计算引擎 (GCE) [持久盘(PD)](http://cloud.google.com/compute/docs/disks) 挂载到您的 Pod 中。 +不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,持久盘卷的内容在删除 Pod 时会被保留,卷只是被卸载掉了。 +这意味着持久盘卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。 + +{{< caution >}} + +您在使用 PD 前,必须使用 `gcloud` 或者 GCE API 或 UI 创建它。 +{{< /caution >}} + + + +使用 `gcePersistentDisk` 时有一些限制: + +* 运行 Pod 的节点必须是 GCE VM +* 那些 VM 必须和持久盘属于相同的 GCE 项目和区域(zone) + + + +PD 的一个特点是它们可以同时被多个消费者以只读方式挂载。 +这意味着您可以用数据集预先填充 PD,然后根据需要并行地在尽可能多的 Pod 中提供该数据集。 +不幸的是,PD 只能由单个使用者以读写模式挂载——即不允许同时写入。 + + + +在由 ReplicationController 所管理的 Pod 上使用 PD 将会失败,除非 PD 是只读模式或者副本的数量是 0 或 1。 + + + +#### 创建持久盘(PD) + +在 Pod 中使用 GCE 持久盘之前,您首先要创建它。 + +```shell +gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk +``` + + + +#### Pod 示例 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-pd +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /test-pd + name: test-volume + volumes: + - name: test-volume + # This GCE PD must already exist. + gcePersistentDisk: + pdName: my-data-disk + fsType: ext4 +``` + + +#### 区域持久盘(Regional Persistent Disks) + +{{< feature-state for_k8s_version="v1.10" state="beta" >}} + + + +[区域持久盘](https://cloud.google.com/compute/docs/disks/#repds) 功能允许您创建能在同一区域的两个可用区中使用的持久盘。 +要使用这个功能,必须以持久盘的方式提供卷;Pod 不支持直接引用这种卷。 + + + +#### 手动供应基于区域 PD 的 PersistentVolume + +使用 [为 GCE PD 定义的存储类](/docs/concepts/storage/storage-classes/#gce) 也可以动态供应。 +在创建 PersistentVolume 之前,您首先要创建 PD。 + +```shell +gcloud beta compute disks create --size=500GB my-data-disk + --region us-central1 + --replica-zones us-central1-a,us-central1-b +``` + + + +PersistentVolume 示例: + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: test-volume + labels: + failure-domain.beta.kubernetes.io/zone: us-central1-a__us-central1-b +spec: + capacity: + storage: 400Gi + accessModes: + - ReadWriteOnce + gcePersistentDisk: + pdName: my-data-disk + fsType: ext4 +``` + + + +### gitRepo (已弃用) + +{{< warning >}} + +gitRepo 卷类型已经被废弃。如果需要在容器中提供 git 仓库,请将一个 [EmptyDir](#emptydir) 卷挂载到 InitContainer 中,使用 git 命令完成仓库的克隆操作,然后将 [EmptyDir](#emptydir) 卷挂载到 Pod 的容器中。 +{{< /warning >}} + + + +`gitRepo` 卷是一个卷插件的例子。 +该卷类型挂载了一个空目录,并将一个 Git 代码仓库克隆到这个目录中供您使用。 +将来,这种卷可能被移动到一个更加解耦的模型中,而不是针对每个应用案例扩展 Kubernetes API。 + +下面给出一个 gitRepo 卷的示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: server +spec: + containers: + - image: nginx + name: nginx + volumeMounts: + - mountPath: /mypath + name: git-volume + volumes: + - name: git-volume + gitRepo: + repository: "git@somewhere:me/my-git-repository.git" + revision: "22f1d8406d464b0c0874075539c1f2e96c253775" +``` + +### glusterfs {#glusterfs} + + + +`glusterfs` 卷能将 [Glusterfs](http://www.gluster.org) (一个开源的网络文件系统) 挂载到您的 Pod 中。 +不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`glusterfs` 卷的内容在删除 Pod 时会被保存,卷只是被卸载掉了。 +这意味着 `glusterfs` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。GlusterFS 可以被多个写者同时挂载。 + +{{< caution >}} + +在使用前您必须先安装运行自己的 GlusterFS。 +{{< /caution >}} + + + +更多详情请参考 [GlusterFS 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/glusterfs)。 + +### hostPath {#hostpath} + + + +`hostPath` 卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中。 +虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。 + + + +例如,`hostPath` 的一些用法有: + +* 运行一个需要访问 Docker 引擎内部机制的容器;请使用 `hostPath` 挂载 `/var/lib/docker` 路径。 +* 在容器中运行 cAdvisor 时,以 `hostPath` 方式挂载 `/sys`。 +* 允许 Pod 指定给定的 `hostPath` 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。 + + + +除了必需的 `path` 属性之外,用户可以选择性地为 `hostPath` 卷指定 `type`。 + +支持的 `type` 值如下: + + + + +| 取值 | 行为 | +|:------|:---------| +| | 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | +| `DirectoryOrCreate` | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 Kubelet 相同的组和所有权。 | +| `Directory` | 在给定路径上必须存在的目录。| +| `FileOrCreate` | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所有权。| +| `File` | 在给定路径上必须存在的文件。| +| `Socket` | 在给定路径上必须存在的 UNIX 套接字。| +| `CharDevice` | 在给定路径上必须存在的字符设备。| +| `BlockDevice` | 在给定路径上必须存在的块设备。| + + + +当使用这种类型的卷时要小心,因为: + +* 具有相同配置(例如从 podTemplate 创建)的多个 Pod 会由于节点上文件的不同而在不同节点上有不同的行为。 +* 当 Kubernetes 按照计划添加资源感知的调度时,这类调度机制将无法考虑由 `hostPath` 使用的资源。 +* 基础主机上创建的文件或目录只能由 root 用户写入。您需要在 [特权容器](/docs/user-guide/security-context) 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 `hostPath` 卷。 + + + +#### Pod 示例 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-pd +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /test-pd + name: test-volume + volumes: + - name: test-volume + hostPath: + # directory location on host + path: /data + # this field is optional + type: Directory +``` + +### iscsi {#iscsi} + + + +`iscsi` 卷能将 iSCSI (基于 IP 的 SCSI) 挂载到您的 Pod 中。 +不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,持久盘 卷的内容在删除 Pod 时会被保存,卷只是被卸载掉了。 +这意味着 `iscsi` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。 + +{{< caution >}} + +在您使用 iSCSI 卷之前,您必须拥有自己的 iSCSI 服务器,并在上面创建卷。 +{{< /caution >}} + + + +iSCSI 的一个特点是它可以同时被多个用户以只读方式挂载。 +这意味着您可以用数据集预先填充卷,然后根据需要在尽可能多的 Pod 上提供它。不幸的是,iSCSI 卷只能由单个使用者以读写模式挂载——不允许同时写入。 + + + +更多详情请参考 [iSCSI 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/iscsi)。 + + + +### local {#local} + +{{< feature-state for_k8s_version="v1.10" state="beta" >}} + +{{< note >}} + +alpha 版本的 PersistentVolume NodeAffinity 注释已被取消,将在将来的版本中废弃。 +用户必须更新现有的使用该注解的 PersistentVolume,以使用新的 PersistentVolume `NodeAffinity` 字段。 +{{< /note >}} + + + +`local` 卷指的是所挂载的某个本地存储设备,例如磁盘、分区或者目录。 + +`local` 卷只能用作静态创建的持久卷。尚不支持动态配置。 + + + +相比 `hostPath` 卷,`local` 卷可以以持久和可移植的方式使用,而无需手动将 Pod 调度到节点,因为系统通过查看 PersistentVolume 所属节点的亲和性配置,就能了解卷的节点约束。 + + + +然而,`local` 卷仍然取决于底层节点的可用性,并不是适合所有应用程序。 +如果节点变得不健康,那么`local` 卷也将变得不可访问,并且使用它的 Pod 将不能运行。 +使用 `local` 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。 + +下面是一个使用 `local` 卷和 `nodeAffinity` 的持久卷示例: + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: example-pv +spec: + capacity: + storage: 100Gi + # volumeMode field requires BlockVolume Alpha feature gate to be enabled. + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Delete + storageClassName: local-storage + local: + path: /mnt/disks/ssd1 + nodeAffinity: + required: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/hostname + operator: In + values: + - example-node +``` + + + +使用 `local` 卷时,需要使用 PersistentVolume 对象的 `nodeAffinity` 字段。 +它使 Kubernetes 调度器能够将使用 `local` 卷的 Pod 正确地调度到合适的节点。 + + + +现在,可以将 PersistentVolume 对象的 `volumeMode` 字段设置为 "Block"(而不是默认值 "Filesystem"),以将 `local` 卷作为原始块设备暴露出来。 +`volumeMode` 字段需要启用 Alpha 功能 `BlockVolume`。 + + + +当使用 `local` 卷时,建议创建一个 StorageClass,将 `volumeBindingMode` 设置为 `WaitForFirstConsumer`。 +请参考 [示例](/docs/concepts/storage/storage-classes/#local)。 +延迟卷绑定操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时,会评估 Pod 可能具有的其他节点约束,例如:如节点资源需求、节点选择器、Pod 亲和性和 Pod 反亲和性。 + + + +您可以在 Kubernetes 之外单独运行静态驱动以改进对 local 卷的生命周期管理。 +请注意,此驱动不支持动态配置。 +有关如何运行外部 `local` 卷驱动的示例,请参考 [local 卷驱动用户指南](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume)。 + +{{< note >}} + +如果不使用外部静态驱动来管理卷的生命周期,则用户需要手动清理和删除 local 类型的持久卷。 +{{< /note >}} + +### nfs {#nfs} + + + +`nfs` 卷能将 NFS (网络文件系统) 挂载到您的 Pod 中。 +不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`nfs` 卷的内容在删除 Pod 时会被保存,卷只是被卸载掉了。 +这意味着 `nfs` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。 + +{{< caution >}} + +在您使用 NFS 卷之前,必须运行自己的 NFS 服务器并将目标 share 导出备用。 +{{< /caution >}} + + + +要了解更多详情请参考 [NFS 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/nfs)。 + +### persistentVolumeClaim {#persistentvolumeclaim} + + +`persistentVolumeClaim` 卷用来将[持久卷](/docs/concepts/storage/persistent-volumes/)(PersistentVolume)挂载到 Pod 中。 +持久卷是用户在不知道特定云环境细节的情况下"申领"持久存储(例如 GCE PersistentDisk 或者 iSCSI 卷)的一种方法。 + + + +更多详情请参考[持久卷示例](/docs/concepts/storage/persistent-volumes/) + +### projected {#projected} + + + +`projected` 卷类型能将若干现有的卷来源映射到同一目录上。 + +目前,可以映射的卷来源类型如下: + +- [`secret`](#secret) +- [`downwardAPI`](#downwardapi) +- [`configMap`](#configmap) +- `serviceAccountToken` + + + +所有的卷来源需要和 Pod 处于相同的命名空间。 +更多详情请参考[一体化卷设计文档](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/node/all-in-one-volume.md)。 + + + +服务帐户令牌的映射是 Kubernetes 1.11 版本中引入的一个功能,并在 1.12 版本中被提升为 Beta 功能。 +若要在 1.11 版本中启用此特性,需要显式设置 `TokenRequestProjection` [功能开关](/docs/reference/command-line-tools-reference/feature-gates/) 为 True。 + + + +#### 包含 secret、downwardAPI 和 configmap 的 Pod 示例如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: volume-test +spec: + containers: + - name: container-test + image: busybox + volumeMounts: + - name: all-in-one + mountPath: "/projected-volume" + readOnly: true + volumes: + - name: all-in-one + projected: + sources: + - secret: + name: mysecret + items: + - key: username + path: my-group/my-username + - downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "cpu_limit" + resourceFieldRef: + containerName: container-test + resource: limits.cpu + - configMap: + name: myconfigmap + items: + - key: config + path: my-group/my-config +``` + + + +带有非默认许可模式设置的多个 secret 的 Pod 示例如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: volume-test +spec: + containers: + - name: container-test + image: busybox + volumeMounts: + - name: all-in-one + mountPath: "/projected-volume" + readOnly: true + volumes: + - name: all-in-one + projected: + sources: + - secret: + name: mysecret + items: + - key: username + path: my-group/my-username + - secret: + name: mysecret2 + items: + - key: password + path: my-group/my-password + mode: 511 +``` + + +每个被投射的卷来源都在 spec 中的 `sources` 内列出。 +参数几乎相同,除了两处例外: + +* 对于 secret,`secretName` 字段已被变更为 `name` 以便与 ConfigMap 命名一致。 +* `defaultMode` 只能根据投射级别指定,而不是针对每个卷来源指定。不过,如上所述,您可以显式地为每个投射项设置 `mode` 值。 + + + +当开启 `TokenRequestProjection` 功能时,可以将当前 [服务帐户](/docs/reference/access-authn-authz/authentication/#service-account-tokens)的令牌注入 Pod 中的指定路径。 +下面是一个例子: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: sa-token-test +spec: + containers: + - name: container-test + image: busybox + volumeMounts: + - name: token-vol + mountPath: "/service-account" + readOnly: true + volumes: + - name: token-vol + projected: + sources: + - serviceAccountToken: + audience: api + expirationSeconds: 3600 + path: token +``` + + + +示例 Pod 具有包含注入服务帐户令牌的映射卷。 +例如,这个令牌可以被 Pod 容器用来访问 Kubernetes API服务器。 +`audience` 字段包含令牌的预期受众。 +令牌的接收者必须使用令牌的受众中指定的标识符来标识自己,否则应拒绝令牌。 +此字段是可选的,默认值是 API 服务器的标识符。 + + + +`expirationSeconds` 是服务帐户令牌的有效期。 +默认值为 1 小时,必须至少 10 分钟(600 秒)。 +管理员还可以通过指定 API 服务器的 `--service-account-max-token-expiration` 选项来限制其最大值。 +`path` 字段指定相对于映射卷的挂载点的相对路径。 + +{{< note >}} + +使用投射卷源作为 [subPath](#using-subpath) 卷挂载的容器将不会接收这些卷源的更新。 +{{< /note >}} + +### portworxVolume {#portworxvolume} + + + +`portworxVolume` 是一个可伸缩的块存储层,能够以超聚合(hyperconverged)的方式与 Kubernetes 一起运行。 +Portworx 支持对服务器上存储的指纹处理、基于存储能力进行分层以及跨多个服务器整合存储容量。 +Portworx 可以以 in-guest 方式在虚拟机中运行,也可以在裸金属 Linux 节点上运行。 + + + +`portworxVolume` 类型的卷可以通过 Kubernetes 动态创建,也可以在 Kubernetes Pod 内预先供应和引用。 +下面是一个引用预先配置的 PortworxVolume 的示例 Pod: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-portworx-volume-pod +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /mnt + name: pxvol + volumes: + - name: pxvol + # This Portworx volume must already exist. + portworxVolume: + volumeID: "pxvol" + fsType: "" +``` + +{{< caution >}} + +在 Pod 中使用 portworxVolume 之前,请确保有一个名为 `pxvol` 的 PortworxVolume 存在。 +{{< /caution >}} + + + +更多详情和示例可以在[这里](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/portworx/README.md)找到。 + +### quobyte {#quobyte} + + + +`quobyte` 卷允许将现有的 [Quobyte](http://www.quobyte.com) 卷挂载到您的 Pod 中。 + +{{< caution >}} + +在使用 Quobyte 卷之前,您首先要进行安装并创建好卷。 + +{{< /caution >}} + + + +更多详情请参考 [Quobyte 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/quobyte)。 + +### rbd {#rbd} + + + +`rbd` 卷允许将 [Rados 块设备](http://ceph.com/docs/master/rbd/rbd/) 卷挂载到您的 Pod 中. +不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`rbd` 卷的内容在删除 Pod 时会被保存,卷只是被卸载掉了。 +这意味着 `rbd` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间"传递"。 + + +{{< caution >}} + +在使用 RBD 之前,您必须安装运行 Ceph。 +{{< /caution >}} + + + +RBD 的一个特点是它可以同时被多个用户以只读方式挂载。 +这意味着您可以用数据集预先填充卷,然后根据需要从尽可能多的 Pod 中并行地提供卷。 +不幸的是,RBD 卷只能由单个使用者以读写模式安装——不允许同时写入。 + +更多详情请参考 [RBD 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/rbd)。 + +### scaleIO {#scaleio} + + + +ScaleIO 是基于软件的存储平台,可以使用现有硬件来创建可伸缩的、共享的而且是网络化的块存储集群。 +`scaleIO` 卷插件允许部署的 Pod 访问现有的 ScaleIO 卷(或者它可以动态地为持久卷申领提供新的卷,参见[ScaleIO 持久卷](/docs/concepts/storage/persistent-volumes/#scaleio))。 + +{{< caution >}} + +在使用前,您必须有个安装完毕且运行正常的 ScaleIO 集群,并且创建好了存储卷。 +{{< /caution >}} + + + +下面是配置了 ScaleIO 的 Pod 示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: pod-0 +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: pod-0 + volumeMounts: + - mountPath: /test-pd + name: vol-0 + volumes: + - name: vol-0 + scaleIO: + gateway: https://localhost:443/api + system: scaleio + protectionDomain: sd0 + storagePool: sp1 + volumeName: vol-0 + secretRef: + name: sio-secret + fsType: xfs +``` + + + +更多详情,请参考 [ScaleIO 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/scaleio)。 + +### secret {#secret} + + + +`secret` 卷用来给 Pod 传递敏感信息,例如密码。您可以将 secret 存储在 Kubernetes API 服务器上,然后以文件的形式挂在到 Pod 中,无需直接与 Kubernetes 耦合。 +`secret` 卷由 tmpfs(基于 RAM 的文件系统)提供存储,因此它们永远不会被写入非易失性(持久化的)存储器。 + +{{< caution >}} + +使用前您必须在 Kubernetes API 中创建 secret。 +{{< /caution >}} + +{{< note >}} + +容器以 [subPath](#using-subpath) 卷的方式挂载 Secret 时,它将感知不到 Secret 的更新。 +{{< /note >}} + + + +Secret 的更多详情请参考[这里](/docs/user-guide/secrets)。 + +### storageOS {#storageos} + + + +`storageos` 卷允许将现有的 [StorageOS](https://www.storageos.com) 卷挂载到您的 Pod 中。 + + + +StorageOS 在 Kubernetes 环境中以容器的形式运行,这使得应用能够从 Kubernetes 集群中的任何节点访问本地或关联的存储。 +为应对节点失效状况,可以复制数据。 +若需提高利用率和降低成本,可以考虑瘦配置(Thin Provisioning)和数据压缩。 + + + +作为其核心能力之一,StorageOS 为容器提供了可以通过文件系统访问的块存储。 + +StorageOS 容器需要 64 位的 Linux,并且没有其他的依赖关系。 +StorageOS 提供免费的开发者授权许可。 + +{{< caution >}} + + +您必须在每个希望访问 StorageOS 卷的或者将向存储资源池贡献存储容量的节点上运行 StorageOS 容器。 +有关安装说明,请参阅 [StorageOS 文档](https://docs.storageos.com)。 + +{{< /caution >}} + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + name: redis + role: master + name: test-storageos-redis +spec: + containers: + - name: master + image: kubernetes/redis:v1 + env: + - name: MASTER + value: "true" + ports: + - containerPort: 6379 + volumeMounts: + - mountPath: /redis-master-data + name: redis-data + volumes: + - name: redis-data + storageos: + # The `redis-vol01` volume must already exist within StorageOS in the `default` namespace. + volumeName: redis-vol01 + fsType: ext4 +``` + + + +更多关于动态供应和持久卷申领的信息请参考 [StorageOS 示例](https://github.com/kubernetes/examples/blob/master/staging/volumes/storageos)。 + +### vsphereVolume {#vspherevolume} + +{{< note >}} + +前提条件:配备了 vSphere 云驱动的 Kubernetes。云驱动的配置方法请参考 [vSphere 使用指南](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/)。 +{{< /note >}} + + + +`vsphereVolume` 用来将 vSphere VMDK 卷挂载到您的 Pod 中。 +在卸载卷时,卷的内容会被保留。 +vSphereVolume 卷类型支持 VMFS 和 VSAN 数据仓库。 + +{{< caution >}} + +在挂载到 Pod 之前,您必须用下列方式之一创建 VMDK。 +{{< /caution >}} + + + +#### 创建 VMDK 卷 + +选择下列方式之一创建 VMDK。 + +{{< tabs name="tabs_volumes" >}} +{{% tab name="使用 vmkfstools 创建" %}} + + + + +首先 ssh 到 ESX,然后使用下面的命令来创建 VMDK: + +```shell +vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk +``` +{{% /tab %}} +{{% tab name="使用 vmware-vdiskmanager 创建" %}} + + + + +使用下面的命令创建 VMDK: + +```shell +vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk +``` +{{% /tab %}} + +{{< /tabs >}} + + + + +#### vSphere VMDK 配置示例 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: test-vmdk +spec: + containers: + - image: k8s.gcr.io/test-webserver + name: test-container + volumeMounts: + - mountPath: /test-vmdk + name: test-volume + volumes: + - name: test-volume + # This VMDK volume must already exist. + vsphereVolume: + volumePath: "[DatastoreName] volumes/myDisk" + fsType: ext4 +``` + + + +更多示例可以在[这里](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere)找到。 + + + +## 使用 subPath + +有时,在单个 Pod 中共享卷以供多方使用是很有用的。 +`volumeMounts.subPath` 属性可用于指定所引用的卷内的子路径,而不是其根路径。 + + + +下面是一个使用同一共享卷的、内含 LAMP 栈(Linux Apache Mysql PHP)的 Pod 的示例。 +HTML 内容被映射到卷的 `html` 文件夹,数据库将被存储在卷的 `mysql` 文件夹中: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-lamp-site +spec: + containers: + - name: mysql + image: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: "rootpasswd" + volumeMounts: + - mountPath: /var/lib/mysql + name: site-data + subPath: mysql + - name: php + image: php:7.0-apache + volumeMounts: + - mountPath: /var/www/html + name: site-data + subPath: html + volumes: + - name: site-data + persistentVolumeClaim: + claimName: my-lamp-site-data +``` + + + +### 使用带有扩展环境变量的 subPath + +{{< feature-state for_k8s_version="v1.11" state="alpha" >}} + + + +`subPath` 的目录名也可以由 Downward API 环境变量构造。 +在使用此特性之前,必须启用 `VolumeSubpathEnvExpansion` 功能开关。 + + + +在这个示例中,Pod 基于 Downward API 中的 Pod 名称,使用 `subPath` 在 hostPath 卷 `/var/log/pods` 中创建目录 `pod1`。 +主机目录 `/var/log/pods/pod1` 挂载到了容器的 `/logs` 中。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: pod1 +spec: + containers: + - name: container1 + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: busybox + command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ] + volumeMounts: + - name: workdir1 + mountPath: /logs + subPath: $(POD_NAME) + restartPolicy: Never + volumes: + - name: workdir1 + hostPath: + path: /var/log/pods +``` + + + +## 资源 + +`emptyDir` 卷的存储介质(磁盘、SSD 等)是由保存 kubelet 根目录(通常是 `/var/lib/kubelet`)的文件系统的介质确定。 +`emptyDir` 卷或者 `hostPath` 卷可以消耗的空间没有限制,容器之间或 Pod 之间也没有隔离。 + + + +将来,我们希望 `emptyDir` 卷和 `hostPath` 卷能够使用 [resource](/docs/user-guide/computeresources) 规范来请求一定量的空间,并且能够为具有多种介质类型的集群选择要使用的介质类型。 + + + +## Out-of-Tree 卷插件 + +Out-of-Tree 卷插件包括容器存储接口(CSI)和 Flexvolume。 +它们使存储供应商能够创建自定义存储插件,而无需将它们添加到 Kubernetes 代码仓库。 + + + +在引入 CSI 和 Flexvolume 之前,所有卷插件(如上面列出的卷类型)都是 "in-tree" 的,这意味着它们是与 Kubernetes 的核心组件一同构建、链接、编译和交付的,并且这些插件都扩展了 Kubernetes 的核心 API。 +这意味着向 Kubernetes 添加新的存储系统(卷插件)需要将代码合并到 Kubernetes 核心代码库中。 + + + +CSI 和 Flexvolume 都允许独立于 Kubernetes 代码库开发卷插件,并作为扩展部署(安装)在 Kubernetes 集群上。 + +对于希望创建 out-of-tree 卷插件的存储供应商,请参考[这个 FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md)。 + +### CSI + +{{< feature-state for_k8s_version="v1.10" state="beta" >}} + + + +[容器存储接口](https://github.com/container-storage-interface/spec/blob/master/spec.md) (CSI) +为容器编排系统(如 Kubernetes)定义标准接口,以将任意存储系统暴露给它们的容器工作负载。 + + + +更多详情请阅读 [CSI 设计方案](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md)。 + +CSI 的支持在 Kubernetes v1.9 中作为 alpha 特性引入,并在 Kubernetes v1.10 中转为 beta 特性。 + + + +一旦在 Kubernetes 集群上部署了 CSI 兼容卷驱动程序,用户就可以使用 `csi` 卷类型来关联、挂载 CSI 驱动程序暴露出来的卷。 + +`csi` 卷类型不支持来自 Pod 的直接引用,只能通过 `PersistentVolumeClaim` 对象在 Pod 中引用。 + +存储管理员可以使用以下字段来配置 CSI 持久卷: + + +- + + `driver`:指定要使用的卷驱动程序名称的字符串值。 + 这个值必须与 CSI 驱动程序在 `GetPluginInfoResponse` 中返回的值相对应;该接口定义在 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#getplugininfo)中。 + Kubernetes 使用所给的值来标识要调用的 CSI 驱动程序;CSI 驱动程序也使用该值来辨识哪些 PV 对象属于该 CSI 驱动程序。 + +- + + `volumeHandle`:唯一标识卷的字符串值。 + 该值必须与CSI 驱动程序在 `CreateVolumeResponse` 的 `volume_id` 字段中返回的值相对应;接口定义在 [CSI spec](https://github.com/container-storageinterface/spec/blob/master/spec.md#createvolume) 中。 + 在所有对 CSI 卷驱动程序的调用中,引用该 CSI 卷时都使用此值作为 `volume_id` 参数。 + +- + + `readOnly`:一个可选的布尔值,指示通过 `ControllerPublished` 关联该卷时是否设置该卷为只读。 + 默认值是 false。 + 该值通过 `ControllerPublishVolumeRequest` 中的 `readonly` 字段传递给 CSI 驱动程序。 + + +- + + `fsType`:如果 PV 的 `VolumeMode` 为 `Filesystem`,那么此字段指定挂载卷时应该使用的文件系统。 + 如果卷尚未格式化,并且支持格式化,此值将用于格式化卷。 + 此值可以通过 `ControllerPublishVolumeRequest`、`NodeStageVolumeRequest` 和 + `NodePublishVolumeRequest` 的 `VolumeCapability` 字段传递给 CSI 驱动。 + + +- + + `volumeAttributes`:一个字符串到字符串的映射表,用来设置卷的静态属性。 + 该映射必须与 CSI 驱动程序返回的 `CreateVolumeResponse` 中的 `volume.attributes` 字段的映射相对应;[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中有相应的定义。 + 该映射通过`ControllerPublishVolumeRequest`、`NodeStageVolumeRequest`、和 `NodePublishVolumeRequest` 中的 `volume_attributes` 字段传递给 CSI 驱动。 + +- + + `controllerPublishSecretRef`:对包含敏感信息的 secret 对象的引用;该敏感信息会被传递给 CSI 驱动来完成 CSI `ControllerPublishVolume` 和 `ControllerUnpublishVolume` 调用。 + 此字段是可选的;在不需要 secret 时可以是空的。 + 如果 secret 对象包含多个 secret,则所有的 secret 都会被传递。 + +- + + `nodeStageSecretRef`:对包含敏感信息的 secret 对象的引用,以传递给 CSI 驱动来完成 CSI `NodeStageVolume` 调用。 + 此字段是可选的,如果不需要 secret,则可能是空的。 + 如果 secret 对象包含多个 secret,则传递所有 secret。 + +- + + `nodePublishSecretRef`:对包含敏感信息的 secret 对象的引用,以传递给 CSI 驱动来完成 CSI ``NodePublishVolume` 调用。 + 此字段是可选的,如果不需要 secret,则可能是空的。 + 如果 secret 对象包含多个 secret,则传递所有 secret。 + + +#### CSI 原始块卷支持 + +{{< feature-state for_k8s_version="v1.11" state="alpha" >}} + + + +从 1.11 版本开始,CSI 引入了对原始块卷的支持。该特性依赖于在 Kubernetes 的之前版本中引入的原始块卷(Raw Block Volume)功能。 +该特性将使具有外部 CSI 驱动程序的供应商能够在 Kubernetes 工作负载中实现原始块卷支持。 + + + +CSI 块卷支持是可选功能,并且默认关闭。 +为了在启用块卷支持的情况下运行 CSI,集群管理员必须使用以下特性开关参数为每个 Kubernetes 组件启用该特性: + +``` +--feature-gates=BlockVolume=true,CSIBlockVolume=true +``` + +学习怎样[安装您的带有块卷支持的 PV/PVC](/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)。 + + +### Flexvolume + + +Flexvolume 是一个自 1.2 版本(在 CSI 之前)以来在 Kubernetes 中一直存在的 out-of-tree 插件接口。 +它使用基于 exec 的模型来与驱动程序对接。 +用户必须在每个节点(在某些情况下是主节点)上的预定义卷插件路径中安装 Flexvolume 驱动程序可执行文件。 + +Pod 通过 `flexvolume` in-tree 插件与 Flexvolume 驱动程序交互。 +更多详情请参考[这里](https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md)。 + + + +## 挂载卷的传播 + +挂载卷的传播能力允许将容器安装的卷共享到同一 Pod 中的其他容器,甚至共享到同一节点上的其他 Pod。 + +卷的挂载传播特性由 Container.volumeMounts 中的 `mountPropagation` 字段控制。 +它的值包括: + + * + `None` - 此卷挂载将不会感知到主机后续在此卷或其任何子目录上执行的挂载变化。 + 类似的,容器所创建的卷挂载在主机上是不可见的。这是默认模式。 + 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)中描述的 `private` 挂载传播选项。 + + * + `HostToContainer` - 此卷挂载将会感知到主机后续针对此卷或其任何子目录的挂载操作。 + + 换句话说,如果主机在此挂载卷中挂载任何内容,容器将能看到它被挂载在那里。 + + 类似的,配置了 `Bidirectional` 挂载传播选项的 Pod 如果在同一卷上挂载了内容,挂载传播设置为 `HostToContainer` 的容器都将能看到这一变化。 + + 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) 中描述的 `rslave` 挂载传播选项。 + + * + --`Bidirectional` - 这种卷挂载和 `HostToContainer` 挂载表现相同。 + + 另外,容器创建的卷挂载将被传播回至主机和使用同一卷的所有 Pod 的所有容器。 + + 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) 中描述的 `rshared` 挂载传播选项。 + + +{{< caution >}} + + +`Bidirectional` 形式的挂载传播可能比较危险。 +它可以破坏主机操作系统,因此它只被允许在特权容器中使用。 +强烈建议您熟悉 Linux 内核行为。 +此外,由 Pod 中的容器创建的任何卷挂载必须在终止时由容器销毁(卸载)。 + +{{< /caution >}} + + +### 配置 + +在某些部署环境中,挂载传播正常工作前,必须在 Docker 中正确配置挂载共享(mount share),如下所示。 + + +编辑您的 Docker `systemd` 服务文件,按下面的方法设置 `MountFlags`: + +```shell +MountFlags=shared +``` + +或者,如果存在 `MountFlags=slave` 就删除掉。然后重启 Docker 守护进程: + +```shell +$ sudo systemctl daemon-reload +$ sudo systemctl restart docker +``` + +{{% capture whatsnext %}} + +参考[使用持久卷部署 WordPress 和 MySQL](/docs/tutorials/stateful-application/mysqlwordpress-persistent-volume/) 示例。 +{{% /capture %}} diff --git a/content/zh/docs/concepts/workloads/_index.md b/content/zh/docs/concepts/workloads/_index.md index 4e1e7855851c3..850d6b64bd22d 100644 --- a/content/zh/docs/concepts/workloads/_index.md +++ b/content/zh/docs/concepts/workloads/_index.md @@ -8,4 +8,4 @@ weight: 50 title: "Workloads" weight: 50 --- ---> \ No newline at end of file +--> diff --git a/content/zh/docs/concepts/workloads/controllers/_index.md b/content/zh/docs/concepts/workloads/controllers/_index.md index 87407c033647e..21c6b5b903529 100644 --- a/content/zh/docs/concepts/workloads/controllers/_index.md +++ b/content/zh/docs/concepts/workloads/controllers/_index.md @@ -1,11 +1,11 @@ - + diff --git a/content/zh/docs/concepts/workloads/controllers/cron-jobs.md b/content/zh/docs/concepts/workloads/controllers/cron-jobs.md index 43f67cb87b7f6..cb6b9bbb45da6 100644 --- a/content/zh/docs/concepts/workloads/controllers/cron-jobs.md +++ b/content/zh/docs/concepts/workloads/controllers/cron-jobs.md @@ -1,71 +1,105 @@ --- -approvers: +reviewers: - erictune - soltysh - janetkuo -title: Cron Job -redirect_from: -- "/docs/concepts/jobs/cron-jobs/" -- "/docs/concepts/jobs/cron-jobs.html" -- "/docs/user-guide/cron-jobs/" -- "/docs/user-guide/cron-jobs.html" +title: CronJob +content_template: templates/concept +weight: 80 --- -{{< toc >}} +{{% capture overview %}} + -## Cron Job 是什么? +_Cron Job_ 创建基于时间调度的 [Jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/)。 -_Cron Job_ 管理基于时间的 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/),即: +一个 CronJob 对象就像 _crontab_ (cron table) 文件中的一行。它用 [Cron](https://en.wikipedia.org/wiki/Cron) 格式进行编写,并周期性的在给定的调度时间执行 Job。 -* 在给定时间点只运行一次 -* 在给定时间点周期性地运行 +{{< note >}} + +所有 **CronJob** 的 `schedule:` 时间都是用 UTC 表示。 +{{< /note >}} -一个 CronJob 对象类似于 _crontab_ (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 [Cron](https://en.wikipedia.org/wiki/Cron) 。 + +有关创建和使用 CronJob 的说明及规范文件的示例,请参见 [使用 CronJob 运行自动任务](/docs/tasks/job/automated-tasks-with-cron-jobs)。 -**注意:** 在预定计划中,问号(`?`)和星号(`*`)的意义是相同的,表示给定字段的取值是任意可用值。 +{{% /capture %}} -**注意:** 在 Kubernetes 1.4 版本引入了 ScheduledJob 资源,但从 1.5 版本开始改成了 CronJob。 -典型的用法如下所示: +{{% capture body %}} + -* 在给定的时间点调度 Job 运行 -* 创建周期性运行的 Job,例如:数据库备份、发送邮件。 +## CronJob 限制 -### 前提条件 +CronJob 创建 Job 对象,每个 Job 的执行次数大约为一次。 +我们之所以说 "大约",是因为在某些情况下,可能会创建两个 Job,或者不会创建任何 Job。 +我们试图使这些情况尽量少发生,但不能完全杜绝。因此,Job 应该是 _幂等的_。 + +如果 `startingDeadlineSeconds` 设置为很大的数值或未设置(默认),并且 `concurrencyPolicy` 设置为 `Allow`,则作业将始终至少运行一次。 -当使用的 Kubernetes 集群,版本 >= 1.4(对 ScheduledJob),>= 1.5(对 CronJob),当启动 API Server(参考 [为集群开启或关闭 API 版本](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster) 获取更多信息)时,通过传递选项 `--runtime-config=batch/v2alpha1=true` 可以开启 batch/v2alpha1 API。 + -## 创建 Cron Job +对于每个 CronJob,CronJob 控制器检查从上一次调度的时间点到现在所错过了调度次数。如果错过的调度次数超过 100 次,那么它就不会启动这个任务,并记录这个错误: -下面是一个 Cron Job 的例子。它会每分钟运行一个 Job,打印出当前时间并输出问候语 hello。 +```` +Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew. -% include code.html language="yaml" file="cronjob.yaml" ghlink="/docs/concepts/workloads/controllers/cronjob.yaml" %} +```` -下载并运行该示例 Cron Job,然后执行如下命令: + -```shell -$ kubectl create -f ./cronjob.yaml -cronjob "hello" created -``` +需要注意的是,如果设置 `startingDeadlineSeconds` 字段非空,则控制器会统计从 `startingDeadlineSeconds` 的值到现在而不是从上一个计划时间到现在错过了多少次 Job。例如,如果 `startingDeadlineSeconds` 是 `200`,则控制器会统计在过去 200 秒中错过了多少次 Job。 + +如果未能在调度时间内创建 CronJob,则计为错过。例如,如果 `concurrencyPolicy` 被设置为 `Forbid`,并且当前有一个调度仍在运行的情况下,试图调度的 CronJob 将被计算为错过。 -可选地,使用 `kubectl run` 创建一个 Cron Job,不需要写完整的配置: + -```shell -$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster" -cronjob "hello" created -``` +例如,假设一个 CronJob 被设置为`08:30:00` 准时开始,它的 `startingDeadlineSeconds` 属性被设置为10,如果在`08:29:00` 时将 CronJob 控制器的时间改为 `08:42:00`,Job 将不会启动。 +如果觉得晚些开始比没有启动好,那请设置一个较长的 `startingDeadlineSeconds`。 + +CronJob 只负责创建与其时间表相匹配的 Job,相应的 Job 又会负责管理它所代表的Pod。 创建该 Cron Job 之后,通过如下命令获取它的状态信息: diff --git a/content/zh/docs/concepts/workloads/controllers/daemonset.md b/content/zh/docs/concepts/workloads/controllers/daemonset.md index 60822051ba29d..e8a79277a8953 100644 --- a/content/zh/docs/concepts/workloads/controllers/daemonset.md +++ b/content/zh/docs/concepts/workloads/controllers/daemonset.md @@ -1,163 +1,416 @@ --- -approvers: +reviewers: +- enisoc - erictune +- foxish +- janetkuo +- kow3ns title: DaemonSet -redirect_from: -- "/docs/admin/daemons/" -- "/docs/admin/daemons.html" +content_template: templates/concept +weight: 50 --- -{{< toc >}} + + +{{% capture overview %}} + + + _DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, +也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。 + + +使用 DaemonSet 的一些典型用法: +- 运行集群存储 daemon,例如在每个节点上运行 `glusterd`、`ceph`。 +- 在每个节点上运行日志收集 daemon,例如`fluentd`、`logstash`。 +- 在每个节点上运行监控 daemon,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、`collectd`、[Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/)、 [AppDynamics 代理](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes)、 [Datadog 代理](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/)、[New Relic 代理](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration), Ganglia `gmond` 或 Instana agent。 + +一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使 +用。 +一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志, +和/或对不同硬件类型具有不同的内存、CPU要求。 -## 什么是 DaemonSet? +{{% /capture %}} - _DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时,也会为他们新增一个 Pod 。 - 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。 - +{{% capture body %}} -使用 DaemonSet 的一些典型用法: + +## 编写 DaemonSet 规约 -一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用。 -一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。 +### 创建 DaemonSet + +您可以在 YAML 文件中描述 DaemonSet。例如,下面的 daemonset.yaml 文件描述了一个运行 fluentd-elasticsearch Docker 镜像的 DaemonSet: -### 必需字段 +{{< codenew file="controllers/daemonset.yaml" >}} + +* 基于 YAML 文件创建 DaemonSet: +``` +kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml +``` + +### 必需字段 +和其它所有 Kubernetes 配置一样,DaemonSet 需要 `apiVersion`、`kind` 和 `metadata` 字段。有关配置文件的基本信息,详见文档 [部署应用](/docs/user-guide/deploying-applications/)、[配置容器](/docs/tasks/) 和 [使用kubectl进行对象管理](/docs/concepts/overview/object-management-kubectl/overview/) 。 DaemonSet 也需要一个 [`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 配置段。 + +### Pod 模板 +`.spec` 唯一必需的字段是 `.spec.template`。 -`.spec.template` 是一个 [Pod 模板](/docs/user-guide/replication-controller/#pod-template)。 -它与 [Pod](/docs/user-guide/pods) 具有相同的 schema,除了它是嵌套的,而且不具有 `apiVersion` 或 `kind` 字段。 +`.spec.template` 是一个 [Pod 模板](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它与 [Pod](/docs/concepts/workloads/pods/pod/) 具有相同的 schema,除了它是嵌套的,而且不具有 `apiVersion` 或 `kind` 字段。 除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 [Pod Selector](#pod-selector))。 在 DaemonSet 中的 Pod 模板必须具有一个值为 `Always` 的 [`RestartPolicy`](/docs/user-guide/pod-states),或者未指定它的值,默认是 `Always`。 + ### Pod Selector -`.spec.selector` 字段表示 Pod Selector,它与 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 或其它资源的 `.spec.selector` 的作用是相同的。 - -`spec.selector` 表示一个对象,它由如下两个字段组成: +`.spec.selector` 字段表示 Pod Selector,它与 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 的 `.spec.selector` 的作用是相同的。 -* `matchLabels` - 与 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/) 的 `.spec.selector` 的作用相同。 -* `matchExpressions` - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表,以及与 key 和 value 列表相关的操作符。 +从 Kubernetes 1.8开始,您必须指定与 `.spec.template` 的标签匹配的 pod selector。当不配置时,pod selector 将不再有默认值。selector 默认与 `kubectl apply` 不兼容。 此外,一旦创建了 DaemonSet,它的 `.spec.selector` 就不能修改。修改 pod selector 可能导致成为 孤儿Pod,并且这对用户来说是困惑的。 + +`spec.selector` 表示一个对象,它由如下两个字段组成: +* `matchLabels` - 与 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/) 的 `.spec.selector` 的作用相同。 +* `matchExpressions` - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表 +,以及与 key 和 value 列表相关的操作符。 +当上述两个字段都指定时,结果表示的是 AND 关系。 -### 仅在某些节点上运行 Pod +如果指定了 `.spec.selector`,必须与 `.spec.template.metadata.labels` 相匹配。如果与它们配置的不匹配,则会被 API 拒绝。 -如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet Controller 将在能够与 [Node Selector](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。 -类似这种情况,可以指定 `.spec.template.spec.affinity`,然后 DaemonSet Controller 将在能够与 [Node Affinity](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。 -如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。 +此外,您通常不应该创建任何 pods,它们的 label 与 selector 匹配,或者直接创建,或者通过另一个 DaemonSet、或者其他控制器,比如 ReplicaSet。否则,DaemonSet 控制器会认为这些 Pod 是由它创建的。Kubernetes 不会阻止你这样做。 您可能希望这样做的一种情况是在节点上手动创建具有不同值的 Pod 以进行测试。 + +### 仅在某些节点上运行 Pod -## 如何调度 Daemon Pod +如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet Controller 将在能够与 [Node Selector](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。类似这种情况,可以指定 `.spec.template.spec.affinity`,然后 DaemonSet Controller 将在能够与 [node Affinity](/docs/concepts/configuration/assign-pod-node/) 匹配>的节点上创建 Pod。 +如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。 -正常情况下,Pod 运行在哪个机器上是由 Kubernetes 调度器来选择的。然而,由 Daemon Controller 创建的 Pod 已经确定了在哪个机器上(Pod 创建时指定了 `.spec.nodeName`),因此: + +## 如何调度 Daemon Pods -Daemon Pod 关心 [Taint 和 Toleration](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),它们会为没有指定 `tolerationSeconds` 的 `node.kubernetes.io/not-ready` 和 `node.alpha.kubernetes.io/unreachable` 的 Taint,创建具有 `NoExecute` 的 Toleration。这确保了当 alpha 特性的 `TaintBasedEvictions` 被启用时,发生节点故障,比如网络分区,这时它们将不会被清除掉(当 `TaintBasedEvictions` 特性没有启用,在这些场景下也不会被清除,但会因为 NodeController 的硬编码行为而被清除,而不会因为 Toleration 导致被清除)。 +### 由 DaemonSet 控制器调度(从v1.12 开始默认禁用) +正常情况下,Pod 运行在哪个机器上是由 Kubernetes 调度器来选择的。然而,由 DaemonSet Controller 创建的 Pod 已经确定了在哪个机器上(Pod 创建时指定了 `.spec.nodeName`,调度器会忽略它),因此: +- DaemonSet Controller 并不关心一个节点的 [`unschedulable`](/docs/admin/node/#manual-node-administration) 字段。 +- DaemonSet Controller 可以创建 Pod,即使调度器还没有启动,这对集群启动是非常有帮助的。 -## 与 Daemon Pod 通信 + +### 由默认 scheduler 调度(从v1.12开始默认开启) + +{{< feature-state state="beta" for-kubernetes-version="1.12" >}} + +DaemonSet 确保所有符合条件的节点都运行一个 Pod 的副本。通常,运行 Pod 的节点由 Kubernetes scheduler 选择。然而,DaemonSet pods 由 DaemonSet controller 创建和调度。这将引入以下问题: + + * Pod 行为的不一致性:等待调度的正常 Pod 已被创建并处于 `Pending` 状态,但 DaemonSet pods 未在 `Pending` 状态下创建。 这使用户感到困惑。 + * [Pod preemption](/docs/concepts/configuration/pod-priority-preemption/)由默认 scheduler 处理。 启用抢占后,DaemonSet 控制器将在不考虑 pod 优先级和抢占的情况下制定调度决策。 + + +`ScheduleDaemonSetPods` 允许您使用默认 scheduler 而不是 DaemonSet 控制器来调度 DaemonSets,方法是将 `NodeAffinity` 添加到 DaemonSet pods,而不是 `.spec.nodeName`。 然后使用默认 scheduler 将 pod 绑定到目标主机。 如果 DaemonSet pod的亲和节点已存在,则替换它。 DaemonSet 控制器仅在创建或修改 DaemonSet pods 时执行这些操作,并且不对 DaemonSet的 `spec.template` 进行任何更改。 + +```yaml +nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: metadata.name + operator: In + values: + - target-host-name +``` + + +此外,`node.kubernetes.io/unschedulable:NoSchedule` toleration 会自动添加到 DaemonSet Pods。 在调度DaemonSet Pod 时,默认调度器会忽略 `unschedulable`节点。 + + +### Taints and Tolerations + +尽管 Daemon Pods 尊重[taints and tolerations](/docs/concepts/configuration/taint-and-toleration),根据相关特性,会自动将以下 tolerations 添加到 DaemonSet Pods 中。 + +| Toleration Key | Effect | Version | Description | +| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ | +| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. | +| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. | +| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | | +| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | | +| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | DaemonSet pods tolerate unschedulable attributes by default scheduler. | +| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler. | + + + + +## 与 Daemon Pods 通信 与 DaemonSet 中的 Pod 进行通信,几种可能的模式如下: - **Push**:配置 DaemonSet 中的 Pod 向其它 Service 发送更新,例如统计数据库。它们没有客户端。 -- **NodeIP 和已知端口**:DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法知道节点 IP 列表,并且基于此也可以知道端口。 -- **DNS**:创建具有相同 Pod Selector 的 [Headless Service](/docs/user-guide/services/#headless-services),然后通过使用 `endpoints` 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。 +- **NodeIP 和已知端口**:DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法知道节点 IP 列表,并且基于此也可以知道端口 +。 +- **DNS**:创建具有相同 Pod Selector 的 [Headless Service](/docs/concepts/services-networking/service/#headless-services),然后通过使用 `endpoints` 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。 - **Service**:创建具有相同 Pod Selector 的 Service,并使用该 Service 随机访问到某个节点上的 daemon(没有办法访问到特定节点)。 + +## 更新 DaemonSet +如果修改了节点标签(Label),DaemonSet 将立刻向新匹配上的节点添加 Pod,同时删除不能够匹配的节点上的 Pod。 +您可以修改 DaemonSet 创建的 Pod。然而,不允许对 Pod 的所有字段进行更新。当下次 +节点(即使具有相同的名称)被创建时,DaemonSet Controller 还会使用最初的模板。 -可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=false` 选项,则 Pod 将被保留在节点上。然后可以创建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 将能够通过标签匹配并识别所有已经存在的 Pod。它不会修改或删除它们,即使是错误匹配了 Pod 模板。通过删除 Pod 或者删除节点,可以强制创建新的 Pod。 +您可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=false` 选项,则 Pod 将被保留在节点上。然后可以创建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 将能够通过标签匹配并识别所有已经存在的 Pod。它不会修改或删除它们,即使是错误匹配了 Pod 模板。通过删除 Pod 或者删除节点,可以强制创建新的 Pod。 + 在 Kubernetes 1.6 或以后版本,可以在 DaemonSet 上 [执行滚动升级](/docs/tasks/manage-daemon/update-daemon-set/)。 -未来的 Kubernetes 版本将支持节点的可控更新。 + ## DaemonSet 的可替代选择 ### init 脚本 我们很可能希望直接在一个节点上启动 daemon 进程(例如,使用 `init`、`upstartd`、或 `systemd`)。这非常好,但基于 DaemonSet 来运行这些进程有如下一些好处: - - - 像对待应用程序一样,具备为 daemon 提供监控和管理日志的能力。 - 为 daemon 和应用程序使用相同的配置语言和工具(如 Pod 模板、`kubectl`)。 -- Kubernetes 未来版本可能会支持对 DaemonSet 创建 Pod 与节点升级工作流进行集成。 - 在资源受限的容器中运行 daemon,能够增加 daemon 和应用容器的隔离性。然而,这也实现了在容器中运行 daemon,但却不能在 Pod 中运行(例如,直接基于 Docker 启动)。 + ### 裸 Pod -可能要直接创建 Pod,同时指定其运行在特定的节点上。 -然而,DaemonSet 替换了由于任何原因被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。由于这个原因,我们应该使用 DaemonSet 而不是单独创建 Pod。 - +可能要直接创建 Pod,同时指定其运行在特定的节点上。然而,DaemonSet 替换了由于任何原因被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。由于这个原因,我们应该使用 DaemonSet 而不是单独创建 Pod。 + ### 静态 Pod 可能需要通过在一个指定目录下编写文件来创建 Pod,该目录受 Kubelet 所监视。这些 Pod 被称为 [静态 Pod](/docs/concepts/cluster-administration/static-pod/)。 -不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的情况下非常有用。 -而且,未来静态 Pod 可能会被废弃掉。 +不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的情况下非常有用。而且,未来静态 Pod 可能会被废弃掉。 + +### Deployments -DaemonSet 与 [Replication Controller](/docs/user-guide/replication-controller) 非常类似,它们都能创建 Pod,这些 Pod 对应的进程都不希望被终止掉(例如,Web 服务器、存储服务器)。 -为无状态的 Service 使用 Replication Controller,比如前端(Frontend)服务,实现对副本的数量进行扩缩容、平滑升级,比之于精确控制 Pod 运行在某个主机上要重要得多。 +DaemonSet 与 [Deployments](/docs/concepts/workloads/controllers/deployment/)非常类似,它们都能创建 Pod,这些 Pod 对应的进程都不希望被终止掉(例如,Web 服务器、存储服务器)。 +为无状态的 Service 使用 Deployments,比如前端 Frontend 服务,实现对副本的数量进行扩缩容、平滑升级,比基于精确控制 Pod 运行在某个主机上要重要得多。 需要 Pod 副本总是运行在全部或特定主机上,并需要先于其他 Pod 启动,当这被认为非常重要时,应该使用 Daemon Controller。 +{{% /capture %}} diff --git a/content/zh/docs/concepts/workloads/controllers/replicaset.md b/content/zh/docs/concepts/workloads/controllers/replicaset.md new file mode 100644 index 0000000000000..8fc47968cb78a --- /dev/null +++ b/content/zh/docs/concepts/workloads/controllers/replicaset.md @@ -0,0 +1,416 @@ +--- +reviewers: +- Kashomon +- bprashanth +- madhusudancs +title: ReplicaSet +content_template: templates/concept +weight: 10 +--- + +{{% capture overview %}} + + + +ReplicaSet 是下一代的 Replication Controller。 _ReplicaSet_ 和 [_Replication Controller_](/docs/concepts/workloads/controllers/replicationcontroller/) 的唯一区别是选择器的支持。ReplicaSet 支持新的基于集合的选择器需求,这在[标签用户指南](/docs/concepts/overview/working-with-objects/labels/#label-selectors)中有描述。而 Replication Controller 仅支持基于相等选择器的需求。 + +{{% /capture %}} + +{{% capture body %}} + + + +## 怎样使用 ReplicaSet + +大多数支持 Replication Controllers 的[`kubectl`](/docs/user-guide/kubectl/)命令也支持 ReplicaSets。但[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) 命令是个例外。如果您想要滚动更新功能请考虑使用 Deployment。[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) 命令是必需的,而 Deployment 是声明性的,因此我们建议通过 [`rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout)命令使用 Deployment。 + +虽然 ReplicaSets 可以独立使用,但今天它主要被[Deployments](/docs/concepts/workloads/controllers/deployment/) 用作协调 Pod 创建、删除和更新的机制。 +当您使用 Deployment 时,您不必担心还要管理它们创建的 ReplicaSet。Deployment 会拥有并管理它们的 ReplicaSet。 + + + +## 什么时候使用 ReplicaSet + +ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 +然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 +因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定义更新业务流程或根本不需要更新。 + +这实际上意味着,您可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义您的应用。 + + +## 示例 + +{{< codenew file="controllers/frontend.yaml" >}} + + + +将此清单保存到 `frontend.yaml` 中,并将其提交到 Kubernetes 集群,应该就能创建 yaml 文件所定义的 ReplicaSet 及其管理的 Pod。 + +```shell +$ kubectl create -f http://k8s.io/examples/controllers/frontend.yaml +replicaset.apps/frontend created +$ kubectl describe rs/frontend +Name: frontend +Namespace: default +Selector: tier=frontend,tier in (frontend) +Labels: app=guestbook + tier=frontend +Annotations: +Replicas: 3 current / 3 desired +Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed +Pod Template: + Labels: app=guestbook + tier=frontend + Containers: + php-redis: + Image: gcr.io/google_samples/gb-frontend:v3 + Port: 80/TCP + Requests: + cpu: 100m + memory: 100Mi + Environment: + GET_HOSTS_FROM: dns + Mounts: + Volumes: +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh + 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy + 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +frontend-9si5l 1/1 Running 0 1m +frontend-dnjpy 1/1 Running 0 1m +frontend-qhloh 1/1 Running 0 1m +``` + + + +## 编写 ReplicaSet Spec + +与所有其他 Kubernetes API 对象一样,ReplicaSet 也需要 `apiVersion`、`kind`、和 `metadata` 字段。有关使用清单的一般信息,请参见 [使用 kubectl 管理对象](/docs/concepts/overview/object-management-kubectl/overview/)。 + +ReplicaSet 也需要 [`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) 部分。 + + + +### Pod 模版 + +`.spec.template` 是 `.spec` 唯一需要的字段。`.spec.template` 是 [Pod 模版](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它和 [Pod](/docs/concepts/workloads/pods/pod/) 的语法几乎完全一样,除了它是嵌套的并没有 `apiVersion` 和 `kind`。 + +除了所需的 Pod 字段之外,ReplicaSet 中的 Pod 模板必须指定适当的标签和适当的重启策略。 + +对于标签,请确保不要与其他控制器重叠。更多信息请参考 [Pod 选择器](#pod-selector)。 + +对于 [重启策略](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy),`.spec.template.spec.restartPolicy` 唯一允许的取值是 `Always`,这也是默认值. + +对于本地容器重新启动,ReplicaSet 委托给了节点上的代理去执行,例如[Kubelet](/docs/admin/kubelet/) 或 Docker 去执行。 + + + +### Pod 选择器 + +`.spec.selector` 字段是[标签选择器](/docs/concepts/overview/working-with-objects/labels/)。ReplicaSet 管理所有标签匹配与标签选择器的 Pod。它不区分自己创建或删除的 Pod 和其他人或进程创建或删除的pod。这允许在不影响运行中的 Pod 的情况下替换副本集。 + +`.spec.template.metadata.labels` 必须匹配 `.spec.selector`,否则它将被 API 拒绝。 + +Kubernetes 1.9 版本中,API 版本 `apps/v1` 中的 ReplicaSet 类型的版本是当前版本并默认开启。API 版本 `apps/v1beta2` 被弃用。 + + + +另外,通常您不应该创建标签与此选择器匹配的任何 Pod,或者直接与另一个 ReplicaSet 或另一个控制器(如 Deployment)标签匹配的任何 Pod。 +如果你这样做,ReplicaSet 会认为它创造了其他 Pod。Kubernetes 并不会阻止您这样做。 + +如果您最终使用了多个具有重叠选择器的控制器,则必须自己负责删除。 + + + +### Replicas + +通过设置 `.spec.replicas` 您可以指定要同时运行多少个 Pod。 +在任何时间运行的 Pod 数量可能高于或低于 `.spec.replicas` 指定的数量,例如在副本刚刚被增加或减少后、或者 Pod 正在被优雅地关闭、以及替换提前开始。 + +如果您没有指定 `.spec.replicas`, 那么默认值为 1。 + + + +## 使用 ReplicaSets 的具体方法 + +### 删除 ReplicaSet 和它的 Pod + +要删除 ReplicaSet 和它的所有 Pod,使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令。 +默认情况下,[垃圾收集器](/docs/concepts/workloads/controllers/garbage-collection/) 自动删除所有依赖的 Pod。 + +当使用 REST API 或 `client-go` 库时,您必须在删除选项中将 `propagationPolicy` 设置为 `Background` 或 `Foreground`。例如: + +```shell +kubectl proxy --port=8080 +curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ +> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ +> -H "Content-Type: application/json" +``` + + + +### 只删除 ReplicaSet + +您可以只删除 ReplicaSet 而不影响它的 Pod,方法是使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令并设置 `--cascade=false` 选项。 + +当使用 REST API 或 `client-go` 库时,您必须将 `propagationPolicy` 设置为 `Orphan`。例如: + +```shell +kubectl proxy --port=8080 +curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ +> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ +> -H "Content-Type: application/json" +``` + + + +一旦删除了原来的 ReplicaSet,就可以创建一个新的来替换它。 +由于新旧 ReplicaSet 的 `.spec.selector` 是相同的,新的 ReplicaSet 将接管老的 Pod。 +但是,它不会努力使现有的 Pod 与新的、不同的 Pod 模板匹配。 +若想要以可控的方式将 Pod 更新到新的 spec,就要使用 [滚动更新](#rolling-updates)的方式。 + + + + +### 将 Pod 从 ReplicaSet 中隔离 + +可以通过改变标签来从 ReplicaSet 的目标集中移除 Pod。这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。 +以这种方式移除的 Pod 将被自动替换(假设副本的数量没有改变)。 + + + +### 缩放 RepliaSet + +通过更新 `.spec.replicas` 字段,ReplicaSet 可以被轻松的进行缩放。ReplicaSet 控制器能确保匹配标签选择器的数量的 Pod 是可用的和可操作的。 + + + +### ReplicaSet 作为水平的 Pod 自动缩放器目标 + +ReplicaSet 也可以作为 [水平的 Pod 缩放器 (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/) 的目标。也就是说,ReplicaSet 可以被 HPA 自动缩放。 +以下是 HPA 以我们在前一个示例中创建的副本集为目标的示例。 + + +{{< codenew file="controllers/hpa-rs.yaml" >}} + + + +将这个列表保存到 `hpa-rs.yaml` 并提交到 Kubernetes 集群,就能创建它所定义的 HPA,进而就能根据复制的 Pod 的 CPU 利用率对目标 ReplicaSet进行自动缩放。 + +```shell +kubectl create -f https://k8s.io/examples/controllers/hpa-rs.yaml +``` + + + +或者,可以使用 `kubectl autoscale` 命令完成相同的操作。 +(而且它更简单!) + +```shell +kubectl autoscale rs frontend +``` + + + +## ReplicaSet 的替代方案 + +### Deployment (推荐) + +[`Deployment`](/docs/concepts/workloads/controllers/deployment/) 是一个高级 API 对象,它以 `kubectl rolling-update` 的方式更新其底层副本集及其Pod。 +如果您需要滚动更新功能,建议使用 Deployment,因为 Deployment 与 `kubectl rolling-update` 不同的是:它是声明式的、服务器端的、并且具有其他特性。 +有关使用 Deployment 来运行无状态应用的更多信息,请参阅 [使用 Deployment 运行无状态应用](/docs/tasks/run-application/run-stateless-application-deployment/)。 + + + +### 裸 Pod + +与用户直接创建 Pod 的情况不同,ReplicaSet 会替换那些由于某些原因被删除或被终止的 Pod,例如在节点故障或破坏性的节点维护(如内核升级)的情况下。 +因为这个好处,我们建议您使用 ReplicaSet,即使应用程序只需要一个 Pod。 +想像一下,ReplicaSet 类似于进程监视器,只不过它在多个节点上监视多个 Pod,而不是在单个节点上监视单个进程。 +ReplicaSet 将本地容器重启的任务委托给了节点上的某个代理(例如,Kubelet 或 Docker)去完成。 + + + +### Job + +使用[`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) 代替ReplicaSet,可以用于那些期望自行终止的 Pod。 + + + +### DaemonSet + +对于管理那些提供主机级别功能(如主机监控和主机日志)的容器,就要用[`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) 而不用 ReplicaSet。 +这些 Pod 的寿命与主机寿命有关:这些 Pod 需要先于主机上的其他 Pod 运行,并且在机器准备重新启动/关闭时安全地终止。 + +{{% /capture %}} + diff --git a/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md b/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md new file mode 100644 index 0000000000000..94b125b690bd3 --- /dev/null +++ b/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md @@ -0,0 +1,546 @@ +--- +title: ReplicationController +feature: + title: 自我修复 + anchor: ReplicationController 如何工作 + description: > + 重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会它们公布给客户端。 + +content_template: templates/concept +weight: 20 +--- + + +{{% capture overview %}} + +{{< note >}} + +现在推荐使用配置 [`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) 的 [`Deployment`](/docs/concepts/workloads/controllers/deployment/) 来建立副本管理机制。 +{{< /note >}} + + +_ReplicationController_ 确保在任何时候都有特定数量的 pod 副本处于运行状态。 +换句话说,ReplicationController 确保一个 pod 或一组同类的 pod 总是可用的。 +{{% /capture %}} + + +{{% capture body %}} + + +## ReplicationController 如何工作 + +当 pods 数量过多时,ReplicationController 会终止多余的 pods。当 pods 数量太少时,ReplicationController 将会启动新的 pods。 +与手动创建的 pod 不同,由 ReplicationController 创建的 pods 在失败、被删除或被终止时会被自动替换。 +例如,在中断性维护(如内核升级)之后,您的 pod 会在节点上重新创建。 +因此,即使您的应用程序只需要一个 pod,您也应该使用一个 ReplicationController。 +ReplicationController 类似于进程管理器,但是 ReplicationController 不是监控单个节点上的单个进程,而是监控跨多个节点的多个 pods。 + +在讨论中,ReplicationController 通常缩写为 "rc" 或 "rcs",并作为 kubectl 命令的快捷方式。 + +一个简单的例子是创建一个 ReplicationController 对象来可靠地无限期地运行 Pod 的一个实例。 +更复杂的用例是运行一个多副本服务(如 web 服务器)的若干相同副本。 + + +## 运行一个示例 ReplicationController + +这个示例 ReplicationController 配置运行 nginx web 服务器的三个副本。 + +{{< codenew file="controllers/replication.yaml" >}} + + +通过下载示例文件并运行以下命令来运行示例任务: + +```shell +kubectl apply -f https://k8s.io/examples/controllers/replication.yaml +``` +``` +replicationcontroller/nginx created +``` + + +使用以下命令检查 ReplicationController 的状态: + +```shell +kubectl describe replicationcontrollers/nginx +``` +``` +Name: nginx +Namespace: default +Selector: app=nginx +Labels: app=nginx +Annotations: +Replicas: 3 current / 3 desired +Pods Status: 0 Running / 3 Waiting / 0 Succeeded / 0 Failed +Pod Template: + Labels: app=nginx + Containers: + nginx: + Image: nginx + Port: 80/TCP + Environment: + Mounts: + Volumes: +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- ---- ------ ------- + 20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-qrm3m + 20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-3ntk0 + 20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-4ok8v +``` + + +此时,创建了三个 pod,但是还没有运行,可能正在拉取镜像。 +稍后,相同的命令可能显示: + +```shell +Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed +``` + + +要以机器可读的形式列出属于 ReplicationController 的所有 pod,可以使用如下命令: + +```shell +pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name}) +echo $pods +``` +``` +nginx-3ntk0 nginx-4ok8v nginx-qrm3m +``` + + +这里,选择器与 ReplicationController 的选择器相同(参见 `kubectl describe` 输出),并以不同的形式出现在 `replication.yaml` 中。 +`--output=jsonpath` 选项指定了一个表达式,只从返回列表中的每个 pod 中获取名称。 + + +## 编写一个 ReplicationController Spec + +与所有其它 Kubernetes 配置一样,ReplicationController 需要 `apiVersion` ,`kind` 和 `metadata` 字段。 +有关使用配置文件的常规信息,参考[对象管理](/docs/concepts/overview/working-with-objects/object-management/)。 + +ReplicationController 也需要一个 [`.spec` 部分](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)。 + + +### Pod 模板 + +`.spec.template` 是 `.spec` 的唯一必需字段。 + +`.spec.template` 是一个 [pod 模板](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它的模式与 [pod](/docs/concepts/workloads/pods/pod/) 完全相同,只是它是嵌套的,并且没有 `apiVersion` 或 `kind`。 + +除了 Pod 所需的字段外,ReplicationController 中的 pod 模板必须指定适当的标签和适当的重新启动策略。 +对于标签,请确保不与其他控制器重叠。参考 [pod 选择器](#pod-选择器)。 + +只允许 [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 等于 `Always`,如果没有指定,这是默认值。 + +对于本地容器重启,ReplicationController 委托给节点上的代理, +例如 [Kubelet](/docs/admin/kubelet/) 或 Docker。 + + +### ReplicationController 上的标签 + +ReplicationController 本身可以有标签 (`.metadata.labels`)。 +通常,您可以将这些设置为 `.spec.template.metadata.labels`; +如果没有指定 `.metadata.labels` 那么它默认为 `.spec.template.metadata.labels`。 +但是,Kubernetes 允许它们是不同的,`.metadata.labels` 不会影响 ReplicationController 的行为。 + + +### Pod 选择器 + +`.spec.selector` 字段是一个[标签选择器](/docs/concepts/overview/working-with-objects/labels/#label-selectors)。 +ReplicationController 管理标签与选择器匹配的所有 Pods。 +它不区分它创建或删除的 pod 以及另一个人或进程创建或删除的 pod。 +这允许在不影响正在运行的 pod 的情况下替换 ReplicationController。 + +如果指定了 `.spec.template.metadata.labels`,它必须和 `.spec.selector` 相同,否则它将被 API 拒绝。 +如果没有指定 `.spec.selector`,它将默认为 `.spec.template.metadata.labels`。 + +此外,用户通常不应创建标签与此选择器匹配的任何其他 Pods,无论是直接创建、使用另一个 ReplicationController 来创建或者别的控制器(如 Job )来创建,都是不允许的。 +如果这样做, ReplicationController 会认为这些 Pods 是由它自己创建的。 +Kubernetes 并没有阻止你这样做。 + +如果您的确创建了多个控制器并且其选择器之间存在重叠,那么您将不得不自己管理删除操作(参考[后文](#使用-replicationcontrollers))。 + + +### 多个副本 + +你可以通过设置 `.spec.replicas` 来指定应该同时运行多少个 Pods。 +在任何时候,处于运行状态的 Pods 个数都可能高于或者低于设定值。例如,副本个数刚刚被增加或减少时,或者一个 pod 处于体面终止过程中而其替代副本已经提前开始创建时。 + +如果你没有指定 `.spec.replicas` ,那么它默认是1。 + + +## 使用 ReplicationController + + +### 删除一个 ReplicationController 以及它的 Pod + +要删除一个 ReplicationController 以及它的 Pod,使用 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete)。 +Kubectl 将 ReplicationController 缩放为0并等待以便在删除 ReplicationController 本身之前删除每个 pod。 +如果这个 kubectl 命令被中断,可以重新启动它。 + +当使用 REST API 或 go 客户端库时,您需要明确地执行这些步骤(缩放副本为0、 等待 Pod 删除,之后删除 ReplicationController 资源)。 + + +### 只删除 ReplicationController + +你可以删除一个 ReplicationController 而不影响它的任何 pod。 + +使用 kubectl ,为 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 指定 `--cascade=false` 选项。 + +当使用 REST API 或 go 客户端库时, 只需删除 ReplicationController 对象。 + +一旦原始对象被删除,你可以创建一个新的 ReplicationController 来替换它。 +只要新的和旧的 `.spec.selector` 相同,那么新的控制器将领养旧的 Pods。 +但是,它不会做出任何努力使现有的 pod 匹配新的、不同的 pod 模板。 +如果希望以受控方式更新 Pods 以使用新的 spec,请执行[滚动更新](#滚动更新)操作。 + + +### 从 ReplicationController 中隔离 pod + +通过更改 Pod 的标签,可以从 ReplicationController 的目标中删除 pod。 +此技术可用于从服务中删除 pod 以进行调试、数据恢复等。以这种方式删除的 pod 将自动替换(假设复制副本的数量也没有更改)。 + + +## 常见的使用模式 + + +### 重新调度 + +如上所述,无论您想要继续运行1个 pod 还是1000个,一个 ReplicationController 都将确保存在指定数量的 pod,即使在节点故障或 pod 终止(例如,由于另一个控制代理的操作)的情况下也是如此。 + +### 扩缩容 + +通过简单地更新 `replicas` 字段,ReplicationController 可以方便地横向扩容或缩容副本的数量,或手动或通过自动缩放控制代理。 + + +### 滚动更新 + +ReplicationController 的设计目的是通过逐个替换 pod 以方便滚动更新服务。 + +如[#1353](http://issue.k8s.io/1353)所述,建议的方法是使用1个副本创建一个新的 ReplicationController,逐个缩放新的(+1)和旧的(-1)控制器,然后在旧的控制器达到0个副本后将其删除。这一方法能够实现可控的 Pods 集合更新,即使存在意外失效的状况。 + +理想情况下,滚动更新控制器将考虑应用程序的就绪情况,并确保在任何给定时间都有足够数量的 Pods 有效地提供服务。 + +这两个 ReplicationController 将需要创建至少具有一个不同标签的 pod,比如 pod 主要容器的镜像标签,因为通常是镜像更新触发滚动更新。 + +滚动更新是在客户端工具 +[`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update)中实现的。 访问 [`kubectl rolling-update` 任务](/docs/tasks/run-application/rolling-update-replication-controller/)以获得更多的具体示例。 + + +### 多个版本跟踪 + +除了在滚动更新过程中运行应用程序的多个版本之外,通常还会使用多个版本跟踪来长时间,甚至持续运行多个版本。这些跟踪将根据标签加以区分。 + +例如,一个服务可能把具有 `tier in (frontend), environment in (prod)` 的所有 pod 作为目标。 +现在假设您有10个副本的 pod 组成了这个层。但是你希望能够'金丝雀部署'这个组件的新版本。 +您可以为大部分副本设置一个 ReplicationController,其中 `replicas` 设置为9,标签为 `tier=frontend, environment=prod, track=stable` 而为 canary 设置另一个 ReplicationController,其中 `replicas` 设置为1,标签为 `tier=frontend, environment=prod, track=canary`。 +现在这个服务覆盖了 canary 和非 canary pod。但您可以单独处理 ReplicationController,以测试、监控结果等。 + + +### 和服务一起使用 ReplicationController + +多个 ReplicationController 可以位于一个服务的后面,例如,一部分流量流向旧版本,一部分流量流向新版本。 + +一个 ReplicationController 永远不会自行终止,但它不会像服务那样长寿。 +服务可以由多个 ReplicationController 控制的 pod 组成,并且在服务的生命周期内(例如,为了执行 pod 更新而运行服务),可以创建和销毁许多 ReplicationController。 +服务本身和它们的客户端都应该忽略负责维护服务 Pod 的 ReplicationController 的存在。 + + +## 编写多副本的应用 + +由 ReplicationController 创建的 Pod 是可替换的,语义上是相同的,尽管随着时间的推移,它们的配置可能会变得异构。 +这显然适合于多副本的无状态服务器,但是 ReplicationController 也可以用于维护主选、分片和工作池应用程序的可用性。 +这样的应用程序应该使用动态的工作分配机制,例如 [RabbitMQ工作队列](https://www.rabbitmq.com/tutorials/tutorial-two-python.html),而不是静态的/一次性定制每个 pod 的配置,这被认为是一种反模式。 +执行的任何 pod 定制,例如资源的垂直自动调整大小(例如,cpu 或内存),都应该由另一个在线控制器进程执行,这与 ReplicationController 本身没什么不同。 + + +## ReplicationController 的职责 + +ReplicationController 只需确保所需的 pod 数量与其标签选择器匹配,并且是可操作的。 +目前,它的计数中只排除终止的 pod。 +未来,可能会考虑系统提供的[就绪状态](http://issue.k8s.io/620)和其他信息,我们可能会对替换策略添加更多控制,我们计划发出事件,这些事件可以被外部客户端用来实现任意复杂的替换和/或缩减策略。 + +ReplicationController 永远被限制在这个狭隘的职责范围内。 +它本身既不执行就绪态探测,也不执行活跃性探测。 +它不负责执行自动缩放,而是由外部自动缩放器控制(如[#492](http://issue.k8s.io/492)中所述),后者负责更改其 `replicas` 字段取值。 +我们不会向 ReplicationController 添加调度策略(例如,[spreading](http://issue.k8s.io/367#issuecomment-48428019))。 +它也不应该验证所控制的 pod 是否与当前指定的模板匹配,因为这会阻碍自动调整大小和其他自动化过程。 +类似地,完成期限、整理依赖关系、配置扩展和其他特性也属于其他地方。 +我们甚至计划考虑批量创建 pod 的机制([#170](http://issue.k8s.io/170))。 + +ReplicationController 旨在成为可组合的构建基元。 +我们希望在它和其他补充原语的基础上构建更高级别的 API 和/或工具,以便于将来的用户使用。 +Kubectl 目前支持的“宏”操作(运行、缩放、滚动更新)就是这方面的概念示例。 +例如,我们可以想象类似于 [Asgard](http://techblog.netflix.com/2012/06/asgaard-web-based-cloud-management-and.html) 的东西管理 ReplicationController、自动定标器、服务、调度策略、 canary 等。 + + +## API 对象 + +在 Kubernetes REST API 中 Replication controller 是顶级资源。 +更多关于 API 对象的详细信息可以在 +[ReplicationController API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replicationcontroller-v1-core)找到。 + + +## ReplicationController 的替代方案 + + +### ReplicaSet + +[`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) 是下一代 ReplicationController ,支持新的[基于集合的标签选择器](/docs/concepts/overview/working-with-objects/labels/#set-based-requirement)。 +它主要被 [`Deployment`](/docs/concepts/workloads/controllers/deployment/) 用来作为一种编排 pod 创建、删除及更新的机制。 +请注意,我们推荐使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定义更新编排或根本不需要更新。 + + +### Deployment (推荐) + +[`Deployment`](/docs/concepts/workloads/controllers/deployment/) 是一种更高级别的 API 对象,它以类似于 `kubectl rolling-update` 的方式更新其底层 ReplicaSet 及其 Pod。 +如果您想要这种滚动更新功能,那么推荐使用 Deployment,因为与 `kubectl rolling-update` 不同,它们是声明式的、服务端的,并且具有其它特性。 + + +### 裸 Pods + +与用户直接创建 pod 的情况不同,ReplicationController 能够替换因某些原因被删除或被终止的 pod ,例如在节点故障或中断节点维护的情况下,例如内核升级。 +因此,我们建议您使用 ReplicationController,即使您的应用程序只需要一个 pod。 +可以将其看作类似于进程管理器,它只管理跨多个节点的多个 pod ,而不是单个节点上的单个进程。 +ReplicationController 将本地容器重启委托给节点上的某个代理(例如,Kubelet 或 Docker)。 + + +### Job + +对于预期会自行终止的 pod (即批处理任务),使用 [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) 而不是 ReplicationController。 + + +### DaemonSet + +对于提供机器级功能(例如机器监控或机器日志记录)的 pod ,使用 [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) 而不是 ReplicationController。 +这些 pod 的生命期与机器的生命期绑定:它们需要在其他 pod 启动之前在机器上运行,并且在机器准备重新启动/关闭时安全地终止。 + + +## 更多信息 + +请阅读[运行无状态的 Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/)。 + +{{% /capture %}} diff --git a/content/zh/docs/concepts/workloads/controllers/statefulset.md b/content/zh/docs/concepts/workloads/controllers/statefulset.md new file mode 100644 index 0000000000000..3ecf219dc41a9 --- /dev/null +++ b/content/zh/docs/concepts/workloads/controllers/statefulset.md @@ -0,0 +1,417 @@ +--- +reviewers: +- enisoc +- erictune +- foxish +- janetkuo +- kow3ns +- smarterclayton +title: StatefulSets +content_template: templates/concept +weight: 40 +--- + + + +{{% capture overview %}} + + + +StatefulSet 是用来管理有状态应用的工作负载 API 对象。 + +{{< note >}} + +**注意:** StatefulSets 是在 1.9 版本中正式发布的。 +{{< /note >}} + +{{< glossary_definition term_id="statefulset" length="all" >}} +{{% /capture %}} + +{{% capture body %}} + + + +## 使用 StatefulSets + +StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值: + +* 稳定的、唯一的网络标识符。 +* 稳定的、持久的存储。 +* 有序的、优雅的部署和缩放。 +* 有序的、自动的滚动更新。 + +在上面,稳定意味着 Pod 调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用一组无状态的副本控制器来部署应用程序,比如 [Deployment](/docs/concepts/workloads/controllers/deployment/) 或者 [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 可能更适用于您的无状态需要。 + + + +## 限制 + +* StatefulSet 在 1.9 版本之前属于 beta 资源,在 1.5 版本之前的任何 Kubernetes 版本中都不可用。 +* 给定 Pod 的存储必须由 [PersistentVolume 驱动](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/README.md) 基于所请求的 `storage class` 来提供,或者由管理员预先提供。 +* 删除和/或收缩 StatefulSet 并*不会*删除它关联的存储卷。这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。 +* StatefulSet 当前需要 [无头服务](/docs/concepts/services-networking/service/#headless-services) 来负责Pod 的网络标识。您需要负责创建此服务。 +* 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。为了实现 StatefulSet 中的 Pod 可以有序和优雅的终止,可以在删除之前将 StatefulSet 缩放为0。 + + + +## 组件 +下面的示例演示了 StatefulSet 的组件。 + +* 名为 nginx 的无头服务用来控制网络域。 +* 名为 web 的 StatefulSet 有一个Spec,它表明将在单个 Pod 中启动 nginx 容器的3个副本。 +* volumeClaimTemplates 将通过 [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) 驱动提供的 PersistentVolume 来提供稳定的存储。 + + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: web +spec: + selector: + matchLabels: + app: nginx # has to match .spec.template.metadata.labels + serviceName: "nginx" + replicas: 3 # by default is 1 + template: + metadata: + labels: + app: nginx # has to match .spec.selector.matchLabels + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: k8s.gcr.io/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 选择器 +您必须设置 StatefulSet 的 `.spec.selector` 字段来匹配它的`.spec.template.metadata.labels`标签。在 Kubernetes 1.8 版本之前,忽略`.spec.selector` 字段会提供默认设置。在 1.8 和以后的版本中,指定的 Pod 选择器匹配失败将在创建 StatefulSet 期间导致验证错误。 + + + +## Pod 的身份 + +StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。该标识和 Pod 是绑定的,不管它被调度在哪个节点上。 + + + +### 序号索引 + +对于具有N个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个整数序号,从 0 到 N-1,该序号在 StatefulSet 上是唯一的。 + + + +### 稳定的网络 ID + +StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。组合主机名的格式为 `$(statefulset name)-$(ordinal)`。上例将会创建三个名称为 `web-0,web-1,web-2` 的三个 Pod。 +StatefulSet 可以使用 [无头服务](/docs/concepts/services-networking/service/#headless-services) 控制它的 Pod 的网络域。管理域的这个服务的格式为: +`$(service name).$(namespace).svc.cluster.local`, 其中 "cluster.local" 是集群域。 + 一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为:`$(podname).$(governing service domain)`,其中管理服务由 StatefulSet 的 `serviceName` 域来定义。 + + + + +下面给出一些选择集群域、服务名、StatefulSet 名、及其怎样影响 StatefulSet 的 Pod 上的 DNS 名称的示例: + +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 >}} + +**注意** 集群域会被设置为 `cluster.local` 除非有[其他配置](/docs/concepts/services-networking/dns-pod-service/#how-it-works)。 +{{< /note >}} + + + +### 稳定的存储 + +Kubernetes 为每个 VolumeClaimTemplate 创建一个 [PersistentVolume](/docs/concepts/storage/persistent-volumes/)。在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass `my-storage-class` 提供的 1 Gib 的 PersistentVolume。如果没有声明 StorageClass,就会使用默认的 StorageClass。当一个 Pod 被安排到节点上时,它的 `volumeMounts` 挂载了与其 PersistentVolumeClaims 相关联的 PersistentVolume。请注意,当 Pod 或者 StatefulSet 被删除时,与PersistentVolumeClaims 相关联的 PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。 + + + + +### Pod 名称标签 + +当 StatefulSet 创建 Pod 时,它会添加一个标签 `statefulset.kubernetes.io/pod-name`,该标签设置为 Pod 名称。这个标签允许您给 StatefulSet 中的特定 Pod 绑定一个 Service。 + + + +## 部署和伸缩保证 + +* 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 {0..N-1}。 +* 当删除 Pod 时,它们是逆序终止的,顺序为 {N-1..0}。 +* 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。 +* 在 Pod 终止之前,所有的继任者必须完全关闭。 + + + +StatefulSet 不应该声明 `pod.Spec.TerminationGracePeriodSeconds` 为 0。这种做法是不安全的,要强烈阻止。更多的解释请参考 [强制删除 StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/)。 + + + +在上面的 nginx 示例被创建后,会按照 web-0、web-1、web-2 的顺序部署三个 Pod。在 web-0 进入[Running 和 Ready](/docs/user-guide/pod-states/)状态前不会部署 web-1。在 web-1 进入Running 和 Ready 状态前不会部署 web-2。如果 web-1 已经处于 Running 和 Ready 状态,而 web-2 尚未部署,在此期间发生了 web-0 运行失败,那么 web-2 将不会被部署,要等到 web-0 部署完成并进入 Running 和 Ready 状态后,才会部署 web-2。 + + + + 如果用户想将示例中的 StatefulSet 收缩为 `replicas=1`,首先被终止的是 web-2。在 web-2 没有被完全停止和删除前,web-1 不会被终止。当 web-2 已被终止和删除、web-1尚未被终止,如果在此期间发生 web-0 运行失败,那么就不会终止 web-1,必须等到 web-0 进入 Running 和 Ready 状态后才会终止 web-1。 + + + +### Pod 管理策略 +在 Kubernetes 1.7及以后的版本中,StatefulSet 允许您放松其排序保证,同时通过它的 `.spec.podManagementPolicy` 域保持其唯一性和身份保证。 + +#### 有序的 Pod 管理 + +`有序的` Pod 管理是 StatefulSet 的默认功能。它实现了 [上面](#deployment-and-scaling-guarantees)描述的行为。 + +#### 并行的 Pod 管理 + +`并行` Pod 管理让 StatefulSet 控制器并行的启动或终止所有的 Pod,启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。 + + + +## 更新策略 + +在 Kubernetes 1.7 及以后的版本中,StatefulSet 的 `.spec.updateStrategy` 字段让您可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求/限制、以及注解。 + + + + +### On Delete + +`OnDelete` 更新策略实现了 1.6 及以前版本的历史遗留行为。当 StatefulSet 的 `.spec.updateStrategy.type` 设置为 `OnDelete` 时,它的控制器将不会自动更新 StatefulSet 中的 Pod。用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 `.spec.template` 的变动作出反应。 + + + + +### 滚动更新(Rolling Updates) + +`RollingUpdate` 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。在没有声明`.spec.updateStrategy`时,`RollingUpdate` 是默认配置。 +当 StatefulSet 的 `.spec.updateStrategy.type` 被设置为 `RollingUpdate` 时,StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 +它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。它会等到被更新的 Pod 进入 Running 和 Ready状态,然后再更新其前身。 + + + +#### 分区 + +通过声明 `.spec.updateStrategy.rollingUpdate.partition`的方式,`RollingUpdate` 更新策略可以实现分区。如果声明了一个分区,当 StatefulSet 的`.spec.template` 被更新时,所有序号大于等于该分区序号的 Pod 都会被更新。所有序号小于该分区序号的 Pod 都不会被更新,并且,即使他们被删除也会依据之前的版本进行重建。如果 StatefulSet 的 `.spec.updateStrategy.rollingUpdate.partition` 大于它的 `.spec.replicas`,对它的 `.spec.template` 的更新将不会传递到它的 Pod。 +在大多数情况下,您不需要使用分区,但如果您希望进行阶段更新、执行金丝雀或执行分阶段展开,则这些分区会非常有用。 + + +{{% /capture %}} +{{% capture whatsnext %}} + + + +* 示例一: [部署有状态应用](/docs/tutorials/stateful-application/basic-stateful-set/)。 +* 示例二: [使用 StatefulSet 部署 Cassandra](/docs/tutorials/stateful-application/cassandra/)。 + + +{{% /capture %}} + diff --git a/content/zh/docs/concepts/workloads/controllers/ttlafterfinished.md b/content/zh/docs/concepts/workloads/controllers/ttlafterfinished.md new file mode 100644 index 0000000000000..def3823e2622c --- /dev/null +++ b/content/zh/docs/concepts/workloads/controllers/ttlafterfinished.md @@ -0,0 +1,120 @@ +--- +reviewers: +- janetkuo +title: 已完成资源的 TTL 控制器 +content_template: templates/concept +weight: 65 +--- + + +{{% capture overview %}} + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + + +TTL 控制器提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。TTL 控制器目前只处理[作业](/docs/concepts/workloads/controllers/jobs-run-to-completion/),可能以后会扩展以处理将完成执行的其他资源,例如 Pod 和自定义资源。 + + +Alpha 免责声明:此功能目前是 alpha 版,可以通过[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) `TTLAfterFinished` 启用。 + + +{{% /capture %}} + + +{{% capture body %}} + + +## TTL 控制器 + + +TTL 控制器现在只支持 Jobs。集群操作员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished` 字段来自动清理已结束的作业(“完成”或“失败”),就像下边的[示例](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)。 + +TTL 控制器假设资源能在执行完成后的 TTL 秒内被清理,也就是当 TTL 过期后。当 TTL 控制器清理资源时,它将做级联删除,即删除资源对象的同时也删除其依赖对象。注意,当资源被删除时,由该资源的生命周期保证其终结器(finalizers)等被执行。 + + +可以随时设置 TTL 秒。以下是设置 Job 的 `.spec.ttlSecondsAfterFinished` 字段的一些示例: + + +* 在资源清单(manifest)中指定此字段,以便作业在完成后的某个时间被自动清除。 +* 将此字段设置为存在的、已完成的资源,以采用此新功能。 +* 在资源创建时使用 [mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 动态设置该字段。集群管理员可以使用它对完成的资源强制执行 TTL 策略。 +* 使用 [mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 在资源完成后动态设置该字段,并根据资源状态、标签等选择不同的 TTL 值。 + + +## 警告 + + +### 更新 TTL 秒 + + +请注意,在创建资源后或已经执行结束后,仍可以修改其 TTL 周期,例如作业的 `.spec.ttlSecondsAfterFinished` 字段。但是,一旦作业变为可被删除状态(当其 TTL 已过期时),即使您通过 API 扩展其 TTL 时长得到了成功的响应,系统也不保证作业将被保留。 + + +### 时间偏差 + + +由于 TTL 控制器使用存储在 Kubernetes 资源中的时间戳来确定 TTL 是否已过期,因此该功能对集群中的时间偏差很敏感,这可能导致 TTL 控制器在错误的时间清理资源对象。 + + +在 Kubernetes 中,需要在所有节点上运行 NTP(参见[#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058))以避免时间偏差。时钟并不总是如此正确,但差异应该很小。设置非零 TTL 时请注意这种风险。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +[自动清理作业](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically) + + +[设计文档](https://github.com/kubernetes/community/blob/master/keps/sig-apps/0026-ttl-after-finish.md) + +{{% /capture %}} diff --git a/content/zh/docs/concepts/workloads/pods/_index.md b/content/zh/docs/concepts/workloads/pods/_index.md index 3b714c7ff5b64..1c35becca5487 100644 --- a/content/zh/docs/concepts/workloads/pods/_index.md +++ b/content/zh/docs/concepts/workloads/pods/_index.md @@ -1,12 +1,11 @@ - + diff --git a/content/zh/docs/concepts/workloads/pods/pod-overview.md b/content/zh/docs/concepts/workloads/pods/pod-overview.md new file mode 100644 index 0000000000000..d96799b1213ca --- /dev/null +++ b/content/zh/docs/concepts/workloads/pods/pod-overview.md @@ -0,0 +1,256 @@ +--- +reviewers: +- erictune +title: Pod 概览 +content_template: templates/concept +weight: 10 +--- + + + +{{% capture overview %}} + +本节提供了 `Pod` 的概览信息,`Pod` 是最小可部署的 Kubernetes 对象模型。 +{{% /capture %}} + + +{{% capture body %}} + + + +## 理解 Pod + +*Pod* 是 Kubernetes 的基本构建块,它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。 +Pod 表示集群上正在运行的进程。 + + + +Pod 封装了应用程序容器(或者在某些情况下封装多个容器)、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。 +Pod 表示部署单元:*Kubernetes 中应用程序的单个实例*,它可能由单个容器或少量紧密耦合并共享资源的容器组成。 + + +[Docker](https://www.docker.com) 是 Kubernetes Pod 中最常用的容器运行时,但 Pod 也能支持其他的容器运行时。 + +Kubernetes 集群中的 Pod 可被用于以下两个主要用途: + + + +* **运行单个容器的 Pod**。"每个 Pod 一个容器"模型是最常见的 Kubernetes 用例;在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。 +* **运行多个协同工作的容器的 Pod**。 +Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。 +这些位于同一位置的容器可能形成单个内聚的服务单元——一个容器将文件从共享卷提供给公众,而另一个单独的“挂斗”容器则刷新或更新这些文件。 +Pod 将这些容器和存储资源打包为一个可管理的实体。 + + + +[Kubernetes 博客](http://kubernetes.io/blog) 上有一些其他的 Pod 用例信息。更多信息请参考: + +* [分布式系统工具包:复合容器的模式](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) +* [容器设计模式](https://kubernetes.io/blog/2016/06/container-design-patterns) + + + +每个 Pod 表示运行给定应用程序的单个实例。如果希望横向扩展应用程序(例如,运行多个实例),则应该使用多个 Pod,每个实例使用一个。 +在 Kubernetes 中,这通常被称为 _副本_。 +通常使用一个称为控制器的抽象来创建和管理一组被复制的 Pod。 +更多信息请参见 [POD 和控制器](#pods-and-controllers)。 + + + +### Pod 怎样管理多个容器 + +Pod 被设计成支持形成内聚服务单元的多个协作过程(作为容器)。 +Pod 中的容器被自动的安排到集群中的同一物理或虚拟机上,并可以一起进行调度。 +容器可以共享资源和依赖、彼此通信、协调何时以及何种方式终止它们。 + + + +注意,在单个 Pod 中将多个并置和共同管理的容器分组是一个相对高级的使用方式。 +只在容器紧密耦合的特定实例中使用此模式。 +例如,您可能有个充当共享卷中文件的 Web 服务器的容器,以及从远程源更新这些文件的单独的"挂斗"容器,如下图所示: + + +{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}} + + + +Pod 为其组成容器提供了两种共享资源:*网络* 和 *存储*。 + + + +#### 联网 + +每个 Pod 分配一个唯一的 IP 地址。 +Pod 中的每个容器共享网络命名空间,包括 IP 地址和网络端口。 +*Pod 内的容器* 可以使用 `localhost` 互相通信。 +当 Pod 中的容器与 *Pod 之外* 的实体通信时,它们必须协调如何使用共享的网络资源(例如端口)。 + + + +#### 存储 + +一个 Pod 可以指定一组共享存储 *卷*。 +Pod 中的所有容器都可以访问共享卷,允许这些容器共享数据。 +卷还允许 Pod 中的持久数据在重启 Pod 中的某个容器时存活。 +有关 Kubernetes 如何在 Pod 中实现共享存储的更多信息,请参考 [卷](/docs/concepts/storage/volumes/)。 + + + +## 使用 Pod + +你很少在 Kubernetes 中直接创建单独的 Pod,甚至是单个存在的 Pod。 +这是因为 Pod 被设计成了相对短暂的一次性的实体。 +当 Pod 由您创建或者间接地由控制器创建时,它被调度在集群中的节点上运行。 +Pod 会保持在该节点上运行,直到进程被终止、Pod 对象被删除、Pod 因资源不足而被 *驱逐* 或者节点失效为止。 +{{< note >}} + +重启 Pod 中的容器不应与重启 Pod 混淆。Pod 本身不运行,而是作为容器运行的环境,并且一直保持到被删除为止。 +{{< /note >}} + + + +Pod 本身并不能自愈。 +如果 Pod 被调度到失败的节点,或者如果调度操作本身失败,则删除该 Pod;同样,由于缺乏资源或进行节点维护,Pod 在被驱逐后将不再生存。 +Kubernetes 使用了一个更高级的称为 *控制器* 的抽象,由它处理相对可丢弃的 Pod 实例的管理工作。 +因此,虽然可以直接使用 Pod,但在 Kubernetes 中,更为常见的是使用控制器管理 Pod。 +有关 Kubernetes 如何使用控制器实现 Pod 伸缩和愈合的更多信息,请参考 [Pod 和控制器](#pods-and-controllers)。 + + + +### Pod 和控制器 + +控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。 +例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。 + + + +包含一个或多个 Pod 的控制器一些示例包括: + +* [Deployment](/docs/concepts/workloads/controllers/deployment/) +* [StatefulSet](/docs/concepts/workloads/controllers/statefulset/) +* [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) + +控制器通常使用您提供的 Pod 模板来创建它所负责的 Pod。 + + + +## Pod 模板 + +Pod 模板是包含在其他对象中的 Pod 规范,例如 +[Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/)、 [Jobs](/docs/concepts/jobs/run-to-completion-finite-workloads/)、和 +[DaemonSets](/docs/concepts/workloads/controllers/daemonset/)。 +控制器使用 Pod 模板来制作实际使用的 Pod。 +下面的示例是一个简单的 Pod 清单,它包含一个打印消息的容器。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: myapp-pod + labels: + app: myapp +spec: + containers: + - name: myapp-container + image: busybox + command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600'] +``` + + + +Pod 模板就像饼干切割器,而不是指定所有副本的当前期望状态。 +一旦饼干被切掉,饼干就与切割器没有关系。 +没有“量子纠缠”。 +随后对模板的更改或甚至切换到新的模板对已经创建的 Pod 没有直接影响。 +类似地,由副本控制器创建的 Pod 随后可以被直接更新。 +这与 Pod 形成有意的对比,Pod 指定了属于 Pod 的所有容器的当前期望状态。 +这种方法从根本上简化了系统语义,增加了原语的灵活性。 + +{{% /capture %}} + +{{% capture whatsnext %}} + +* 进一步了解 Pod 的行为: + * [Pod 的终止](/docs/concepts/workloads/pods/pod/#termination-of-pods) + * 其他 Pod 话题 +{{% /capture %}} diff --git a/content/zh/docs/concepts/workloads/pods/pod.md b/content/zh/docs/concepts/workloads/pods/pod.md new file mode 100644 index 0000000000000..3b35674ccaa06 --- /dev/null +++ b/content/zh/docs/concepts/workloads/pods/pod.md @@ -0,0 +1,399 @@ +--- +reviewers: +title: Pods +content_template: templates/concept +weight: 20 +--- + + + +{{% capture overview %}} + + + +_Pods_ 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。 + +{{% /capture %}} + + +{{% capture body %}} + + + +## Pod 是什么? + +_pod_ (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器(例如 Docker 容器),这些容器有共享存储、网络、以及怎样运行这些容器的声明。Pod 的内容总是共同定位和共同调度,并且在共享的上下文中运行。 +Pod 以特定于应用的“逻辑主机”为模型,它包含一个或多个应用容器,这些容器是相对紧密的耦合在一起;在容器出现之前,在相同的物理机或虚拟机上运行意味着在相同的逻辑主机上运行。 + + + +虽然 Kubernetes 支持多种容器运行时,但 Docker 是最常见的一种运行时,它有助于描述 Docker 术语中的 Pod。 + +Pod 的共享上下文是一组 Linux 命名空间、cgroups、以及其他潜在的资源隔离相关的因素,这些相同的东西也隔离了 Docker 容器。在 Pod 的上下文中,单个应用程序可能还会应用进一步的子隔离。 + + + +Pod 中的所有容器共享一个 IP 地址和端口空间,并且可以通过 `localhost` 互相发现。他们也能通过标准的进程间通信(如 SystemV 信号量或 POSIX 共享内存)方式进行互相通信。不同 Pod 中的容器的 IP 地址互不相同,没有 [特殊配置](/docs/concepts/policy/pod-security-policy/) 就不能使用 IPC 进行通信。这些容器之间经常通过 Pod IP 地址进行通信。 + +Pod 中的应用也能访问共享卷,共享卷是 Pod 定义的一部分,可被用来挂载到每个应用的文件系统上。 + + + +在 [Docker](https://www.docker.com/) 体系的术语中,Pod 被建模为一组具有共享命名空间和共享 [卷](/docs/concepts/storage/volumes/) 的 Docker 容器。 + +与单个应用程序容器一样,Pod被认为是相对短暂的(而不是持久的)实体。如 [Pod 的生命](/docs/concepts/workloads/pods/pod-lifecycle/) 所讨论的那样:Pod 被创建、给它指定一个唯一 ID (UID)、被调度到节点、在节点上存续直到终止(取决于重启策略)或被删除。如果节点宕机,调度到该节点上的 Pod 会在一个超时周期后被安排删除。给定 Pod (由 UID 定义)不会重新调度到新节点;相反,它会被一个完全相同的 Pod 替换掉,如果需要甚至连 Pod 名称都可以一样,除了 UID 是新的(更多信息请查阅 [副本控制器(replication +controller)](/docs/concepts/workloads/controllers/replicationcontroller/))。 + + + +当某些东西被说成与 Pod(如卷)具有相同的生存期时,这意味着只要pod(具有该UID)存在,它就存在。如果那个 Pod 因为某种原因被删除了,即使创建了相同的 Pod 做替换,Pod 的相关的资源(如卷等)也会被销毁进行重新创建。 + +{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}} + + + +包含多个容器的 Pod 包含文件拉取器和 web 服务器,使用了持久卷在容器之间进行存储共享。 + +{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}} + + + + +## Pod 的动机 + +### 管理 + +Pod 是形成内聚服务单元的多个协作过程模式的模型。它们提供了一个比它们的应用组成集合更高级的抽象,从而简化了应用的部署和管理。Pod 可以用作部署单元、水平缩放和复制。在 Pod中,多个容器的共同定位(协同调度)、共享命运(例如,终止)、协调复制、资源共享和依赖项管理都是自动处理的。 + + + + +### 资源共享和通信 + +Pod 使它的组成容器间能够进行数据共享和通信。 + +Pod 中的应用都使用相同的网络命名空间(相同 IP 和 端口空间),而且能够互相“发现”并使用 `localhost` 进行通信。因此,在 Pod 中的应用必须协调它们的端口使用情况。每个 Pod 在扁平的共享网络空间中具有一个IP地址,该空间能与整个网络上的其他物理机或虚拟机进行完全通信。 + + + +主机名被设置为 Pod 内的应用程序容器的 Pod 名称。请参考[组网的更多信息](/docs/concepts/cluster-administration/networking/)。 + +Pod 除了定义了 Pod 中运行的应用程序容器之外,Pod 还指定了一组共享存储卷。该共享存储卷能使数据在容器重新启动后继续保留,并能在 Pod 内的应用程序之间共享。 + + + +## 使用 Pod + +Pod 可以用于托管垂直集成的应用程序栈(例如,LAMP),但最主要的动机是支持位于同一位置的、共同管理的帮助程序,例如: + +* 内容管理系统、文件和数据加载器、本地缓存管理器等。 +* 日志和检查点备份、压缩、旋转、快照等。 +* 数据更改监视器、日志跟踪器、日志和监视适配器、事件发布器等。 +* 代理、桥接器和适配器 +* 控制器、管理器、配置器和更新器 + + + + +通常,单个 Pod 并不打算运行同一应用程序的多个实例。 + +更多解释,请参考 [分布式系统工具包:复合容器的模式](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) + + + +## 备选方案的思考 + +_为什么不在单个(Docker)容器中运行多个程序?_ + +1. 透明度。Pod 内的容器对基础设施可见,使得基础设施能够向这些容器提供服务,例如流程管理和资源监控。这为用户提供了许多便利。 +1. 解耦软件依赖关系。可以独立地对单个容器进行版本控制、重新构建和重新部署。Kubernetes 有一天甚至可能支持单个容器的实时更新。 +1. 易用性。用户不需要运行他们自己的进程管理器、也不用担心信号和退出代码传播等。 +1. 效率。因为基础结构承担了更多的责任,所以容器可以变得更加轻量化。 + + + +_为什么不支持基于亲和性的容器联合调度?_ + +这种处理方法尽管可以提供同址,但不能提供 Pod 的大部分好处,如资源共享、IPC、有保证的命运共享和简化的管理。 + + + +## Pod 的持久性(或稀缺性) + +Pod 并没想被视为持久的实体。它们无法在调度失败、节点故障或其他驱逐策略(例如由于缺乏资源或在节点维护的情况下)中生存。 + +一般来说,用户不需要直接创建 Pod。他们几乎都是使用控制器进行创建,即使对于单例的创建也一样使用控制器,例如 [Deployments](/docs/concepts/workloads/controllers/deployment/)。 +控制器提供集群范围的自修复以及复制和滚动管理。 +像 [StatefulSet](/docs/concepts/workloads/controllers/statefulset.md) 这样的控制器还可以提供支持有状态的 Pod。 + + + +在集群调度系统中,使用 API 合集作为面向用户的主要原语是比较常见的,包括 [Borg](https://research.google.com/pubs/pub43438.html)、[Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html)、[Aurora](http://aurora.apache.org/documentation/latest/reference/configuration/#job-schema)、和 [Tupperware](http://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997)。 + + + +Pod 暴露为原语是为了便于: + +* 调度器和控制器可插拔性 +* 支持 Pod 级别的操作,而不需要通过控制器 API "代理" 它们 +* Pod 生命与控制器生命的解耦,如自举 +* 控制器和服务的解耦;端点控制器只监视 Pod +* Kubelet 级别的功能与集群级别功能的清晰组合;Kubelet 实际上是 "Pod 控制器" +* 高可用性应用程序期望在 Pod 终止之前并且肯定要在 Pod 被删除之前替换 Pod,例如在计划驱逐或镜像预先提取的情况下。 + + + +## Pod 的终止 + +因为 Pod 代表在集群中的节点上运行的进程,所以当不再需要这些进程时(与被 KILL 信号粗暴地杀死并且没有机会清理相比),允许这些进程优雅地终止是非常重要的。 +用户应该能够请求删除并且知道进程何时终止,但是也能够确保删除最终完成。当用户请求删除 Pod 时,系统会记录在允许强制删除 Pod 之前所期望的宽限期,并向每个容器中的主进程发送 TERM 信号。一旦过了宽限期,KILL 信号就发送到这些进程,然后就从 API 服务器上删除 Pod。如果 Kubelet 或容器管理器在等待进程终止时发生重启,则终止操作将以完整的宽限期进行重试。 + + + + +流程示例: + +1. 用户发送命令删除 Pod,使用的是默认的宽限期(30秒) +2. API 服务器中的 Pod 会随着宽限期规定的时间进行更新,过了这个时间 Pod 就会被认为已 "死亡"。 +3. 当使用客户端命令查询 Pod 状态时,Pod 显示为 "Terminating"。 +4. (和第3步同步进行)当 Kubelet 看到 Pod 由于步骤2中设置的时间而被标记为 terminating 状态时,它就开始执行关闭 Pod 流程。 + 1. 如果 Pod 定义了 [preStop 钩子](/docs/concepts/containers/container-lifecycle-hooks/#hook-details),就在 Pod 内部调用它。如果宽限期结束了 `preStop` 钩子还在运行,那么就用小的(2秒)扩展宽限期调用步骤2。 + + 2. 给 Pod 内的进程发送 TERM 信号。 +5. (和第3步同步进行)从服务的端点列表中删除 Pod,Pod也不再被视为副本控制器的运行状态的 Pod 集的一部分。当负载平衡器(如服务代理)将 Pod 从轮换中移除时,关闭迟缓的 Pod 将不能继续为流量服务。 +6. 当宽限期结束后,Pod 中运行的任何进程都将被用 SIGKILL 杀死。 +7. Kubelet 将通过设置宽限期为0(立即删除)来完成删除 API 服务器上的 Pod。Pod 从 API 中消失,从客户端也不再可见。 + + + + +默认情况下,所有删除在30秒内都是优雅的。`kubectl delete` 命令支持 `--grace-period=` 选项,允许用户覆盖默认值并声明他们自己的宽限期。设置为 ‘0’ 会[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) Pod。在 kubectl 1.5以后的版本(含1.5版本)中,为了执行强制删除,您还必须为 `--grace-period=0` 声明一个额外的 `--force` 标志。 + + + +### Pod 的强制删除 + +强制删除pod定义为从集群状态和 etcd 中立即删除 Pod。当执行强制删除时,apiserver 并不会等待 kubelet 的确认信息,该 Pod 已在所运行的节点上被终止了。强制删除操作从 API 中立即清除了 Pod, 因此可以用相同的名称创建一个新的 Pod。在节点上,设置为立即终止的 Pod 还是会在被强制删除前设置一个小的宽限期。 + +强制删除对某些 Pod 可能具有潜在危险,因此应该谨慎地执行。对于 StatefulSet 管理的 Pod,请参考 [从 StatefulSet 中删除 Pod](/docs/tasks/run-application/force-delete-stateful-set-pod/)的任务文档。 + + + +## Pod 容器的特权模式 + +从 Kubernetes v1.1 开始,Pod 内的任何容器都可以开启特权模式,开启的方法是在容器声明中的 `SecurityContext` 域使用 `privileged` 标志。这对于希望使用linux功能(如操作网络堆栈和访问设备)的容器非常有用。容器内的进程获得的特权与容器外的进程几乎相同。使用特权模式,将网络和卷插件编写为不需要编译到 kubelet 中的独立的 Pod 应该更容易。 + +如果主节点的 Kubernetes 版本是 v1.1 或更高,而工作节点的版本低于 v1.1,新的特权 Pod 将被 API 服务器接受,但不会被启动。它们将处于 pending 状态。如果用户使用命令 `kubectl describe pod FooPodName`,就可以看到 Pod 处于 pending 状态的原因。`describe` 命令的输出事件列表将显示: +`Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'` + + + +如果主节点的版本低于 v1.1,那么特权 Pod 就不能被创建。如果用户尝试创建有特权容器的 Pod,将会得到下面的错误信息: +`The Pod "FooPodName" is invalid. +spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'` + + + +## API 对象 + +Pod 是 Kubernetes REST API 中的顶级资源。关于该 API 对象的更详细信息请参考 [Pod API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)。 diff --git a/content/zh/docs/concepts/workloads/pods/podpreset.md b/content/zh/docs/concepts/workloads/pods/podpreset.md index 81b9f5d4db0cd..23106c2d66d1f 100644 --- a/content/zh/docs/concepts/workloads/pods/podpreset.md +++ b/content/zh/docs/concepts/workloads/pods/podpreset.md @@ -1,72 +1,151 @@ --- -approvers: +reviewers: - jessfraz title: Pod Preset content_template: templates/concept +weight: 50 --- {{% capture overview %}} -本文提供了 PodPreset 的概述。 在 pod 创建时,用户可以使用 `podpreset` 对象将特定信息注入 -pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。 + +本文提供了 PodPreset 的概述。 在 Pod 创建时,用户可以使用 PodPreset 对象将特定信息注入 Pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。 {{% /capture %}} -{{< toc >}} {{% capture body %}} + + + ## 理解 Pod Preset -`Pod Preset` 是一种 API 资源,在 pod 创建时,用户可以用它将额外的运行时需求信息注入 pod。 -使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 pod。 +`Pod Preset` 是一种 API 资源,在 Pod 创建时,用户可以用它将额外的运行时需求信息注入 Pod。 +使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 Pod。 + + + +使用 Pod Preset 使得 Pod 模板编写者不必显式地为每个 Pod 设置信息。 +这样,使用特定服务的 Pod 模板编写者不需要了解该服务的所有细节。 -使用 Pod Preset 使得 pod 模板编写者不必显式地为每个 pod 设置信息。 -这样,使用特定服务的 pod 模板编写者不需要了解该服务的所有细节。 + 了解更多的相关背景信息,请参考 [ PodPreset 设计提案](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)。 + + ## PodPreset 如何工作 Kubernetes 提供了准入控制器 (`PodPreset`),该控制器被启用时,会将 Pod Preset -应用于接收到的 pod 创建请求中。 -当出现 pod 创建请求时,系统会执行以下操作: +应用于接收到的 Pod 创建请求中。 +当出现 Pod 创建请求时,系统会执行以下操作: + + 1. 检索所有可用 `PodPresets` 。 -1. 检查 `PodPreset` 的标签选择器与要创建的 pod 的标签是否匹配。 -1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 pod。 -1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 pod。 -1. 为改动的 pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如: +1. 检查 `PodPreset` 的标签选择器与要创建的 Pod 的标签是否匹配。 +1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 Pod。 +1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 Pod。 +1. 为改动的 Pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如: `podpreset.admission.kubernetes.io/podpreset-": ""`。 + + 一个 Pod 可能不与任何 Pod Preset 匹配,也可能匹配多个 Pod Preset。 同时,一个 `PodPreset` 可能不应用于任何 Pod,也可能应用于多个 Pod。 当 `PodPreset` 应用于一个或多个 Pod 时,Kubernetes 修改 pod spec。 对于 `Env`、 `EnvFrom` 和 `VolumeMounts` 的改动, Kubernetes 修改 pod 中所有容器的规格,对于卷的改动,Kubernetes 修改 Pod spec。 + {{< note >}} -**注意:** Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段, -但是不会应用于 `initContainers` 字段。 + + +Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段,但是不会应用于 `initContainers` 字段。 {{< /note >}} + + ### 为特定 Pod 禁用 Pod Preset -在一些情况下,用户不希望 pod 被 pod preset 所改动,这时,用户可以在 pod spec 中添加形如 - `podpreset.admission.kubernetes.io/exclude: "true"` 的注解。 +在一些情况下,用户不希望 Pod 被 Pod Preset 所改动,这时,用户可以在 Pod spec 中添加形如 `podpreset.admission.kubernetes.io/exclude: "true"` 的注解。 + + ## 启用 Pod Preset 为了在集群中使用 Pod Preset,必须确保以下几点: -1. 已启用 api 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的 - `--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。 -1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control` - 配置项中包含 `PodPreset` 。 -1. 已经通过在相应的名字空间中创建 `PodPreset` 对象,定义了 Pod preset。 - -{{% /capture %}} + -{{% capture whatsnext %}} +1. 已启用 API 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的 `--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。 +1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control` 配置项中包含 `PodPreset` 。 +1. 已经通过在相应的命名空间中创建 `PodPreset` 对象,定义了 Pod Preset。 -* [使用 PodPreset 将信息注入 Pods](/docs/tasks/inject-data-application/podpreset/) {{% /capture %}} - +{{% capture whatsnext %}} + +* [使用 PodPreset 将信息注入 Pod](/docs/tasks/inject-data-application/podpreset/) +{{% /capture %}} diff --git a/content/zh/docs/contribute/_index.md b/content/zh/docs/contribute/_index.md new file mode 100644 index 0000000000000..a3ec22713b5f5 --- /dev/null +++ b/content/zh/docs/contribute/_index.md @@ -0,0 +1,173 @@ +--- +content_template: templates/concept +title: 为 Kubernetes 文档做贡献 +linktitle: 贡献 +main_menu: true +weight: 80 +--- + + + +{{% capture overview %}} + + + +如果你想帮助对 Kubernetes 文档或网站做出贡献,我们很高兴得到你的帮助! +任何人都可以做出贡献,无论你刚参与项目还是参与了很长时间,无论你是开发人员还是用户,或是无法忍受看到拼写错误的人。 + + + +更多途径参与 Kubernetes 社区或了解我们,请访问 [Kubernetes 社区网站](/community/)。 + + + +查找 [样式指南](/docs/contribute/style/style-guide/) 或者 [Kubernetes 社区网站](/community/)? + +{{% /capture %}} + +{{% capture body %}} + + + +## 贡献者类型 + + + +- [签署了 CLA](/docs/contribute/start#sign-the-cla)并为项目贡献了时间和精力的 Kubernetes 组织的_成员_。 + 参见 [社区成员](https://github.com/kubernetes/community/blob/master/community-membership.md) 中对于成员资格的具体标准。 + + + +- SIG Docs 的_评审者_是对评审文档 PR 感兴趣,并被 SIG Docs 审批者添加到 Github 群组并在 Github 仓库中 `OWNERS` 文件的 Kubernetes 组织的成员。 + + + +- SIG Docs 的_审批者_是对项目持续贡献,并被授予合并 PR 权限和代表 Kubernetes 组织发布内容的成员。 + 批准人也可以在更广泛的 Kubernetes 社区中代表 SIG Docs 团队。 + SIG Docs审批者的一些职责,如协调发布版本,需要大量的时间投入。 + + + +## 贡献途径 + + + +以下列表将工作分成了:任何人都可以做的工作、Kubernetes 组织成员可以做的工作,和熟悉 SIG Docs 流程并且有更高访问权限才能做的工作。 +持续的贡献可以帮助你理解已有的工具和组织决策。 + + + +你对 Kubernetes 文档可以做出的贡献不仅限于列表列出的条目,但它可以帮助你开动起来。 + + + +- [任何人](/docs/contribute/start/) + - 登记记录可修正的错误 + + + +- [成员](/docs/contribute/start/) + - 完善已有文档 + - 在 Slack 或 SIG Docs 邮件列表中提出改进意见 + - 提升文档的易用性 + - 对 PR 提出无约束的反馈 + - 编写博文和案例分析 + + + +- [评审者](/docs/contribute/intermediate/) + - 为新功能特性编写文档 + - 对 issue 进行筛选和分类 + - 评审 PR + - 创建图表、图形分析和嵌入式的屏幕/视频 + - 本地化 + - 作为 docs 小组的代表为其他项目仓库做贡献 + - 在代码中编辑面向用户的字符串 + - 改进代码注释和 Godoc + + + +- [审批者](/docs/contribute/advanced/) + - 通过批准和合并 PR 发布贡献成果 + - 作为 docs 团队的代表参与 Kubernetes 发布团队 + - 对样式指南提出改进建议 + - 对文档测试提出改进建议 + - 对 Kubernetes 网站或其他工具提出改进建议 + +{{% /capture %}} diff --git a/content/zh/docs/contribute/advanced.md b/content/zh/docs/contribute/advanced.md new file mode 100644 index 0000000000000..7df7d280f3dfa --- /dev/null +++ b/content/zh/docs/contribute/advanced.md @@ -0,0 +1,232 @@ +--- +title: 高级贡献 +slug: advanced +content_template: templates/concept +weight: 30 +--- + + + +{{% capture overview %}} + + + +如果你已经阅读并掌握[开始贡献](/docs/contribute/start/)和[中级贡献](/docs/contribute/intermediate/),并准备了解更多贡献的途径,请阅读此文。 +您需要使用 Git 命令行工具和其他工具做这些工作。 + +{{% /capture %}} + +{{% capture body %}} + + + +## 做一周的 PR 管理者 + + + +SIG Docs 的[审批者](/docs/contribute/participating/#approvers)可以成为 PR 管理者。 + + + +SIG Docs 的审批者会每周轮换地加入到 [PR 管理者轮换日程](https://github.com/kubernetes/website/wiki/PR-Wranglers)中。 +PR 管理者的工作职责包括: + + + +- 每天评审新增的 PR + - 指导新的贡献者签署 CLA,关闭两周都没有签署 CLA 的提交人的 PR。 + PR 提交人在签署 CLA 之后可以重启 PR,所以 PR 管理者需要保证这段时间内相关文件没有合入。 + - 对改进建议的更新提供反馈信息,包括促成其他 SIG 成员的技术性评审。 + - 合入符合要求的 PR,关闭不符合要求的 PR。 +- 每天筛选和标记新增的 issue。参见[中级贡献](/docs/contribute/intermediate/)中有关 SIG Docs 成员使用 metadata 的指南。 + + + +## 提出改进建议 + + + +SIG Docs 的[成员](/docs/contribute/participating/#members)可以提出改进建议。 + + + +在对 Kubernetes 文档贡献了一段时间后,你可能会对样式指南、用于构建文档的工具链、网页样式、评审和合入 PR 的流程,或者文档的其他方面产生改进的想法。为了尽可能透明化,这些提议都需要在 SIG Docs 会议或 [kubernetes-sig-docs 邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)上讨论。此外,在提出全面的改进之前,它能真正帮助我们了解有关“当前工作如何运作”和“以往的决定是为何做出”的背景。想了解文档的当前运作方式,最快的途径是咨询 [kubernetes.slack.com](https://kubernetes.slack.com) 中的 `#sig-docs` 聊天群组。 + + + +在进行了讨论并且 SIG 就期望的结果达成一致之后,你就能以最合理的方式处理改进建议了。例如,样式指南或网站功能的更新可能涉及 PR 的新增,而与文档测试相关的更改可能涉及 sig-testing。 + + + +## 为 Kubernetes 版本发布协调文档 + + + +SIG Docs 的[审批者](/docs/contribute/participating/#approvers)可以为 Kubernetes 版本发布协调文档。 + + + +每一个 Kubernetes 版本都是由参与 sig-release 的 SIG(特别兴趣小组)的一个团队协调的。指定版本的发布团队中还包括总体发布牵头人,以及来自 sig-pm、sig-testing 的代表等。了解更多关于 Kubernetes 版本发布的流程,请参考 [https://github.com/kubernetes/sig-release](https://github.com/kubernetes/sig-release)。 + + + +SIG Docs 团队的代表需要为一个指定的版本协调以下工作: + + + +- 通过特性跟踪表来监视新功能特性或现有功能特性的修改。如果版本的某个功能特性的文档没有为发布做好准备,那么该功能特性不允许进入发布版本。 + + + +- 定期参加 sig-release 会议并对文档状态进行更新。 + + + +- 评审和修改由负责实现某功能特性的 SIG 起草的功能特性文档。 + + + +- 合入版本发布相关的 PR,并为对应发布版本维护 Git 特性分支。 + + + +- 指导那些想学习并有意愿担当该角色的 SIG Docs 贡献者。这就是我们常说的“实习”。 + + + +- 发布版本的制品发布时,相关的文档更新也需要发布。 + + + +协调一个版本发布通常需要 3-4 个月的时间投入,该任务由 SIG Docs 审批者轮流承担。 + + + +## 保荐新的贡献者 + + + +SIG Docs 的[评审者](/docs/contribute/participating/#reviewers)可以保荐新的贡献者。 + + + +新的贡献者针对一个或多个 Kubernetes 项目仓库成功提交了 5 个实质性 PR 之后,就有资格申请 Kubernetes 组织[成员](/docs/contribute/participating#members)。贡献者的成员资格需要同时得到两位评审者的保荐。 + + + +新的文档贡献者可以通过咨询 [Kubernetes Slack instance](https://kubernetes.slack.com) 上的 #sig-docs 或 [SIG Docs 邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) 来请求评审者保荐。如果你对申请人的工作充满信心,你自愿保荐他们。当他们提交成员资格申请时,回复“+1”并详细说明为什么你认为申请人适合加入 Kubernetes 组织。 + +{{% /capture %}} + diff --git a/content/zh/docs/contribute/generate-ref-docs/_index.md b/content/zh/docs/contribute/generate-ref-docs/_index.md new file mode 100644 index 0000000000000..ac5f61a40f883 --- /dev/null +++ b/content/zh/docs/contribute/generate-ref-docs/_index.md @@ -0,0 +1,21 @@ +--- +title: 参考文档概述 +main_menu: true +weight: 80 +--- + + + + + +许多 Kubernetes 参考文档都是使用脚本从 Kubernetes 源代码生成的。本节的主题是如何生成这种类型的文档。 diff --git a/content/zh/docs/contribute/generate-ref-docs/federation-api.md b/content/zh/docs/contribute/generate-ref-docs/federation-api.md new file mode 100644 index 0000000000000..c4023ab8a4848 --- /dev/null +++ b/content/zh/docs/contribute/generate-ref-docs/federation-api.md @@ -0,0 +1,152 @@ +--- +title: 为 Kubernetes 联邦 API 生成参考文档 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +本节介绍如何为 Kubernetes 联邦 API 自动生成参考文档。 + +{{% /capture %}} + + +{{% capture prerequisites %}} + + + +* 你需要安装 [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)。 + + + +* 你需要安装 1.9.1 或更高版本的 [Golang](https://golang.org/doc/install),并在环境变量中设置你的 `$GOPATH`。 + + + +* 你需要安装 [Docker](https://docs.docker.com/engine/installation/)。 + + + +* 你需要知道如何在一个 GitHub 项目仓库中创建一个 PR。一般来说,这涉及到创建仓库的一个分支。想了解更多信息,请参见[创建一个文档 PR](/docs/home/contribute/create-pull-request/)。 + +{{% /capture %}} + + +{{% capture steps %}} + + + +## 运行 update-federation-api-docs.sh 脚本 + + + +如果你还没有 Kubernetes 联邦的源码,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/federation +``` + + + +确定本地 [kubernetes/federation](https://github.com/kubernetes/federation) 仓库的主目录。 +例如,如果按照前面的步骤获取联邦的源码,则主目录是 `$GOPATH/src/github.com/kubernetes/federation`。 +下文将该目录称为 ``。 + + + +运行文档生成脚本: + +```shell +cd +hack/update-federation-api-reference-docs.sh +``` + + + +脚本运行 [k8s.gcr.io/gen-swagger-docs](https://console.cloud.google.com/gcr/images/google-containers/GLOBAL/gen-swagger-docs?gcrImageListquery=%255B%255D&gcrImageListpage=%257B%2522t%2522%253A%2522%2522%252C%2522i%2522%253A0%257D&gcrImageListsize=50&gcrImageListsort=%255B%257B%2522p%2522%253A%2522uploaded%2522%252C%2522s%2522%253Afalse%257D%255D) 镜像来生成以下参考文档: + +* /docs/api-reference/extensions/v1beta1/operations.html +* /docs/api-reference/extensions/v1beta1/definitions.html +* /docs/api-reference/v1/operations.html +* /docs/api-reference/v1/definitions.html + + + +生成的文件不会被自动发布。你必须手工将它们复制到 [kubernetes/website](https://github.com/kubernetes/website/tree/master/content/en/docs/reference/generated) 仓库。 + + + +以下文件发布在 [kubernetes.io/docs/reference](/docs/reference/): + +* [Federation API v1 Operations](/docs/reference/federation/v1/operations/) +* [Federation API v1 Definitions](/docs/reference/federation/v1/definitions/) +* [Federation API extensions/v1beta1 Operations](/docs/reference/federation/extensions/v1beta1/operations/) +* [Federation API extensions/v1beta1 Definitions](/docs/reference/federation/extensions/v1beta1/definitions/) + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* [为 Kubernetes API 生成参考文档](/docs/home/contribute/generated-reference/kubernetes-api/) +* [为 kubectl 命令集生成参考文档](/docs/home/contribute/generated-reference/kubectl/) +* [为 Kubernetes 组件和工具生成参考页](/docs/home/contribute/generated-reference/kubernetes-components/) + +{{% /capture %}} diff --git a/content/zh/docs/contribute/generate-ref-docs/kubectl.md b/content/zh/docs/contribute/generate-ref-docs/kubectl.md new file mode 100644 index 0000000000000..ae64df1dc2378 --- /dev/null +++ b/content/zh/docs/contribute/generate-ref-docs/kubectl.md @@ -0,0 +1,473 @@ +--- +title: 为 kubectl 命令集生成参考文档 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +该页面显示了如何自动生成 `kubectl` 工具提供的命令的参考页面。 + +{{< note >}} + + +本主题展示了如何为 [kubectl 命令集](/docs/reference/generated/kubectl/kubectl-commands) 生成参考文档,如 [kubectl apply](/docs/reference/generated/kubectl/kubectl-commands#apply) 和 [kubectl taint](/docs/reference/generated/kubectl/kubectl-commands#taint)。 + + + +本主题没有展示如何生成 [kubectl](/docs/reference/generated/kubectl/kubectl/) 组件的参考页面。相关说明请参见[为 Kubernetes 组件和工具生成参考页面](/docs/home/contribute/generated-reference/kubernetes-components/)。 +{{< /note >}} + +{{% /capture %}} + + +{{% capture prerequisites %}} + + + +* 你需要安装 [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)。 + + + +* 你需要安装 1.9.1 或更高版本的 [Golang](https://golang.org/doc/install), 并在环境变量中设置 `$GOPATH`。 + + + +* 你需要安装 [Docker](https://docs.docker.com/engine/installation/)。 + + + +* 你需要知道如何在一个 GitHub 项目仓库中创建一个 PR。一般来说,这涉及到创建仓库的一个分支。想了解更多信息,请参见[创建一个文档 PR](/docs/home/contribute/create-pull-request/) 和 [GitHub 标准 Fork&PR 工作流](https://gist.github.com/Chaser324/ce0505fbed06b947d962)。 + +{{% /capture %}} + + +{{% capture steps %}} + + + +## 下载三个仓库 + + + +如果你还没有下载过 kubernetes/kubernetes 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/kubernetes +``` + + + +确定 [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/kubernetes`。下文将该目录称为 ``。 + + + +如果你还没有下载过 kubernetes/website 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/website +``` + + + +确定 [kubernetes/website](https://github.com/kubernetes/website) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/website`。下文将该目录称为 ``。 + + + +如果你还没有下载过 kubernetes-incubator/reference-docs 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes-incubator/reference-docs +``` + + + +确定 [kubernetes-incubator/reference-docs](https://github.com/kubernetes-incubator/reference-docs) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes-incubator/reference-docs`。下文将该目录称为 ``。 + + + +进入 kubernetes/kubernetes 仓库的本地目录,检出感兴趣的分支,并确保它是最新的。例如,如果希望为 Kubernetes 1.9 生成文档,可以使用以下命令: + +```shell +cd +git checkout release-1.9 +git pull https://github.com/kubernetes/kubernetes release-1.9 +``` + + + +## 编辑 kubectl 源码 + + + +kubectl 命令集的参考文档是基于 kubectl 源码自动生成的。如果想要修改参考文档,可以从修改 kubectl 源码中的一个或多个注释开始。在本地 kubernetes/kubernetes 仓库中进行修改,然后向 [github.com/kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 的 master 分支提交 PR。 + + + +[PR 56673](https://github.com/kubernetes/kubernetes/pull/56673/files) 是一个对 kubectl 源码中的笔误进行修复的 PR 示例。 + + + +跟踪你的 PR,并回应评审人的评论。继续跟踪你的 PR,直到它合入到 kubernetes/kubernetes 仓库的 master 分支中。 + + + +## 以 cherry-pick 方式将你的修改合入已发布分支 + + + +你的修改已合入 master 分支中,该分支用于开发下一个 Kubernetes 版本。如果你希望修改部分出现在已发布的 Kubernetes 版本文档中,则需要提议将它们以 cherry-pick 方式合入已发布分支。 + + + +例如,假设 master 分支正用于开发 Kubernetes 1.10 版本,而你希望将修改合入到已发布的 1.9 版本分支。相关的操作指南,请参见 [提议一个 cherry-pick 合入](https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md)。 + + + +跟踪你的 cherry-pick PR,直到它合入到已发布分支中。 + +{{< note >}} + + +提议一个 cherry-pick 合入,需要你有在 PR 中设置标签和里程碑的权限。如果你没有,你需要与有权限为你设置标签和里程碑的人合作完成。 +{{< /note >}} + + + +## 编辑 Makefile + + + +进入 `` 目录, 打开 `Makefile` 进行编辑: + + + +将 `K8SROOT` 设置为 kubernetes/kubernetes 仓库的本地主目录。将 `WEBROOT` 设置为 kubernetes/website 仓库的本地主目录。将 `MINOR_VERSION` 设置为要构建的文档的副版本号。例如,如果要为 Kubernetes 1.9 版本构建文档,请将 `MINOR_VERSION` 设置为 9。保存并关闭 `Makefile`。 + + + +## 制作 brodocs 镜像 + + + +文档生成代码需要 `pwittrock/brodocs` Docker 镜像。 + + + +该命令用于创建 `pwittrock/brodocs` Docker 镜像。它还尝试将镜像推送到 DockerHub,但是如果该步骤失败也没关系。只要镜像在本地,就可以成功生成代码。 + + +```shell +make brodocs +``` + + + +确认 brodocs 镜像是否存在: + +```shell +docker images +``` + + + +输出显示 `pwittrock/brodocs` 是可用镜像之一: + +```shell +REPOSITORY TAG IMAGE ID CREATED SIZE +pwittrock/brodocs latest 999d34a50d56 5 weeks ago 714MB +``` + + + +## 创建版本目录 + + + +在 `gen-kubectldocs/generators` 目录中,如果你还没有一个名为 `v1_MINOR_VERSION` 的目录,那么现在通过复制前一版本的目录来创建一个。例如,假设你想要为 Kubernetes 1.9 版本生成文档,但是还没有 `v1_9` 目录,这时可以通过运行以下命令来创建并填充 `v1_9` 目录: + +```shell +mkdir gen-kubectldocs/generators/v1_9 +cp -r gen-kubectldocs/generators/v1_8/* gen-kubectldocs/generators/v1_9 +``` + + + +## 从 kubernetes/kubernetes 检出一个分支 + + + +在本地 kubernetes/kubernetes 仓库中,检出你想要生成文档的、包含 Kubernetes 版本的分支。例如,如果希望为 Kubernetes 1.9 版本生成文档,请检出 1.9 分支。确保本地分支是最新的。 + + + +## 运行文档生成代码 + + + +在 kubernetes-incubator/reference-docs 仓库的本地目录中,构建并运行文档生成代码。你可能需要以 root 用户运行命令: + +```shell +cd +make cli +``` + + + +## 找到生成的文件 + + + +这两个文件是成功构建的主要产物。验证它们是否存在: + +* `/gen-kubectldocs/generators/build/index.html` +* `/gen-kubectldocs/generators/build/navData.js` + + + +## 将文件复制到 kubernetes/website 仓库 + + + +将生成的文件从 kubernetes-incubator/reference-docs 仓库的本地目录复制到 kubernetes/website 仓库的本地目录。 + +```shell +cd +make copycli +``` + + + +## 在 kubernetes/website 中添加和提交修改 + + + +列出生成并准备合入到 `kubernetes/website` 仓库中的文件: + +``` +cd +git status +``` + + + +输出展示了新增和修改的文件。例如,输出可能如下所示: + +```shell +modified: docs/reference/generated/kubectl/kubectl-commands.html +modified: docs/reference/generated/kubectl/navData.js +``` + + + +运行 `git add` 和 `git commit` 将提交上述文件。 + + + +## 创建 PR + + + +对 `kubernetes/website` 仓库创建 PR。跟踪你的 PR,并根据需要回应评审人的评论。继续跟踪你的 PR,直到它被合入。 + + + +在 PR 合入的几分钟后,你更新的参考主题将出现在[已发布文档](/docs/home/)中。 + + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* [为 Kubernetes 组件和工具生成参考文档](/docs/home/contribute/generated-reference/kubernetes-components/) +* [为 Kubernetes API 生成参考文档](/docs/home/contribute/generated-reference/kubernetes-api/) +* [为 Kubernetes 联邦 API 生成参考文档](/docs/home/contribute/generated-reference/federation-api/) + +{{% /capture %}} + + + diff --git a/content/zh/docs/contribute/generate-ref-docs/kubernetes-api.md b/content/zh/docs/contribute/generate-ref-docs/kubernetes-api.md new file mode 100644 index 0000000000000..ccacc307d1675 --- /dev/null +++ b/content/zh/docs/contribute/generate-ref-docs/kubernetes-api.md @@ -0,0 +1,685 @@ +--- +title: 为 Kubernetes API 生成参考文档 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +本页面展示了如何为 Kubernetes API 更新自动生成的参考文档。 + +{{% /capture %}} + + +{{% capture prerequisites %}} + + + +你需要安装以下软件: + + + +* [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* 1.9 或更高版本的 [Golang](https://golang.org/doc/install) +* [Docker](https://docs.docker.com/engine/installation/) +* [etcd](https://github.com/coreos/etcd/) + + + +在环境变量中设置 $GOPATH,并且 etcd 的路径必须配置在 $PATH 环境变量中。 + + + +你需要知道如何在一个 GitHub 项目仓库中创建一个 PR。一般来说,这涉及到创建仓库的一个分支。想了解更多信息,请参见[创建一个文档 PR](/docs/home/contribute/create-pull-request/) 和 [GitHub 标准 Fork&PR 工作流](https://gist.github.com/Chaser324/ce0505fbed06b947d962)。 + +{{% /capture %}} + + +{{% capture steps %}} + + + +## 概述 + + + +更新 Kubernetes API 参考文档有两个步骤: + + + +1. 从 kubernetes 源码生成 OpenAPI 规范。本步骤的工具在 [kubernetes/kubernetes/hack](https://github.com/kubernetes/kubernetes/tree/master/hack)。 + + + +1. 从 OpenAPI 规范生成 HTML 文件。本步骤的工具在 [kubernetes-incubator/reference-docs](https://github.com/kubernetes-incubator/reference-docs)。 + + + +## 下载三个仓库 + + + +If you don't already have the kubernetes/kubernetes repository, get it now: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/kubernetes +``` + + + +确定 [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/kubernetes`。下文将该目录称为 ``。 + + + +如果你还没有下载过 `kubernetes/website` 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/website +``` + + + +确定 [kubernetes/website](https://github.com/kubernetes/website) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/website`。下文将该目录称为 ``。 + + + +如果你还没有下载过 kubernetes-incubator/reference-docs 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes-incubator/reference-docs +``` + + + +确定 [kubernetes-incubator/reference-docs](https://github.com/kubernetes-incubator/reference-docs) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes-incubator/reference-docs`。下文将该目录称为 ``。 + + + +## 编辑 Kubernetes 源码 + + + +Kubernetes API 参考文档是基于 OpenAPI 规范自动生成的,而该规范是从 Kubernetes 源码生成的。如果想要修改参考文档,可以从修改 Kubernetes 源码中的一个或多个注释开始。 + + + +### 修改源码中的注释 + +{{< note >}} + + +以下步骤是一个示例,而不是通用步骤。在你操作过程中,细节会有所不同。 +{{< /note >}} + + + +下面是在 Kubernetes 源码中编辑注释的示例。 + + + +进入 kubernetes/kubernetes 仓库的本地目录,检出 master 分支,并确保它是最新的: + +```shell +cd +git checkout master +git pull https://github.com/kubernetes/kubernetes master +``` + + + +假设 master 分支中的这个源文件有一个拼写错误 "atmost": + +[kubernetes/kubernetes/staging/src/k8s.io/api/apps/v1/types.go](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/apps/v1/types.go) + + + +在本地环境中,打开 `types.go` 文件,然后将 "atmost" 修改为 "at most"。 + + + +确认文件已修改: + +```shell +git status +``` + + + +输出展示了在 master 分支上,`types.go` 文件已被修改: + +```shell +On branch master +... + modified: staging/src/k8s.io/api/apps/v1/types.go +``` + + + +### 提交已编辑的文件 + + + +运行 `git add` 和 `git commit` 提交到目前为止所做的修改。在下一步中,你将进行第二次提交。将修改拆分为两个提交是很重要的。 + + + +### 生成 OpenAPI 规范和相关文件 + + + +进入 `` 目录运行以下脚本: + +```shell +hack/update-generated-swagger-docs.sh +hack/update-swagger-spec.sh +hack/update-openapi-spec.sh +hack/update-generated-protobuf.sh +hack/update-api-reference-docs.sh +``` + + + +运行 `git status` 查看生成的文件。 + +```shell +On branch master +... + modified: api/openapi-spec/swagger.json + modified: api/swagger-spec/apps_v1.json + modified: docs/api-reference/apps/v1/definitions.html + modified: staging/src/k8s.io/api/apps/v1/generated.proto + modified: staging/src/k8s.io/api/apps/v1/types.go + modified: staging/src/k8s.io/api/apps/v1/types_swagger_doc_generated.go +``` + + + +检查 `api/openapi-spec/swagger.json` 的内容确认拼写错误是否被修复。例如,你可以运行 `git diff -a api/openapi-spec/swagger.json`。这个步骤很重要,因为 `swagger.json` 是文档生成过程的第二个步骤的输入。 + + + +运行 `git add` 和 `git commit` 提交修改。现在你有两个提交:一个是已编辑的 `types.go` 文件,另一个是已生成的 OpenAPI 规范和相关文件。把这两个提交分开。也就是说,不要将它们合并提交。 + + + +将你的修改以 [pull request](https://help.github.com/articles/creating-a-pull-request/) 提交到 [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 仓库的 master 分支。跟踪你的 PR,并根据需要回应评审人的评论。继续跟踪你的 PR,直到它被合入。 + + + +[PR 57758](https://github.com/kubernetes/kubernetes/pull/57758) 是一个对 Kubernetes 源码中的拼写错误进行修复的 PR 示例。 + +{{< note >}} + + +定位要修改的具体源文件可能很困难。在前面的示例中,正确的源文件位于 `kubernetes/kubernetes` 仓库的 `staging` 目录下。但在你的情况下,`staging` 目录可能不是查找正确源的位置。有关指导,请查看 [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes/tree/master/staging) 仓库的 `README` 文件和相关仓库 [kubernetes/apiserver](https://github.com/kubernetes/apiserver/blob/master/README.md)。 +{{< /note >}} + + + +### 以 cherry-pick 方式将你的提交合入已发布分支 + + + +在上文中,你在 master 分支中编辑了一个文件,然后运行脚本来生成 OpenAPI 规范和相关文件。然后你在一个 PR 中向 kubernetes/kubernetes 仓库的 master 分支提交了修改。现在假设你想要将你的修改合入到一个发布分支中。例如,假设 master 分支用于开发 Kubernetes 1.10 版本,而你希望将你的修改合入到 release-1.9 分支中。 + + + +回想一下 PR 中有两个提交:一个用于编辑 `types.go`,另一个用于脚本生成的文件。下一步是对你在 release-1.9 分支的第一次提交提议一个 cherry-pick 合入。其目的是挑出对 `types.go` 的编辑的那次提交,而不是对运行脚本结果的提交。有关说明,请参见[提议一个 cherry-pick 合入](https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md)。 + +{{< note >}} + + +提议一个 cherry-pick 合入,需要你有在 PR 中设置标签和里程碑的权限。如果你没有,你需要与有权限为你设置标签和里程碑的人合作完成。 +{{< /note >}} + + + +当你有一个对 release-1.9 分支进行 cherry-pick 合入的 PR 时,下一步是在 release-1.9 分支的本地环境中运行这些脚本。 + +```shell +hack/update-generated-swagger-docs.sh +hack/update-swagger-spec.sh +hack/update-openapi-spec.sh +hack/update-generated-protobuf.sh +hack/update-api-reference-docs.sh +``` + + + +现在向 cherry pick 的 PR 添加一个提交,该 PR 包含最近生成的 OpenAPI 规范和相关文件。跟踪你的 PR,直到它合入到 release-1.9 分支中。 + + + +此时,master 和 release-1.9 分支都更新了 `types.go` 文件和一组生成的文件,这些反映了你对 `types.go` 做的修改。注意,在 release-1.9 分支中生成的 OpenAPI 规范和其他文件不一定与在 master 分支中生成的文件相同。在 release-1.9 分支中生成的文件只包含 Kubernetes 1.9 版本的 API 元素。master 分支中生成的文件可能包含正在 1.10 版本中开发的 API 元素,而这些元素却不在 1.9 版本中。 + + + +## 生成已发布的参考文档 + + + +前一章节展示了如何编辑源文件,然后生成几个文件,包括 `kubernetes/kubernetes` 仓库中的 `api/openapi-spec/swagger.json`。 + + + +本章节介绍如何生成[已发布的 Kubernetes API 参考文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/),该文档由 [kubernetes-incubator/reference-docs](https://github.com/kubernetes-incubator/reference-docs) 中的工具生成。这些工具以 `api/openapi-spec/swagger.json` 文件作为输入。 + + + +### 在 kubernetes-incubator/reference-docs 仓库中编辑 Makefile 文件 + + + +进入 `` 目录, 打开 `Makefile` 进行编辑: + + + +将 `K8SROOT` 设置为 kubernetes/kubernetes 仓库的本地主目录。将 `WEBROOT` 设置为 kubernetes/website 仓库的本地主目录。将 `MINOR_VERSION` 设置为要构建的文档的副版本号。例如,如果要为 Kubernetes 1.9 版本构建文档,请将 `MINOR_VERSION` 设置为 9。保存并关闭 `Makefile`。 + + + +### 复制 OpenAPI 规范 + + + +文档生成代码需要 Kubernetes API 的 OpenAPI 规范的本地副本。进入 `` 目录,检出有你想要使用的 OpenAPI 规范的分支。例如,如果要为 Kubernetes 1.9 版本生成文档,请检出 release-1.9 分支。 + + + +返回 `` 目录。输入以下命令将 OpenAPI 规范从 `kubernetes/kubernetes` 仓库复制到本地目录: + +```shell +make updateapispec +``` + + + +输出显示文件已被复制: + +```shell +cp ~/src/github.com/kubernetes/kubernetes/api/openapi-spec/swagger.json gen-apidocs/generators/openapi-spec/swagger.json +``` + + + +### 制作 brodocs 镜像 + + + +文档生成代码需要 [pwittrock/brodocs](https://github.com/pwittrock/brodocs) Docker 镜像。 + + + +该命令用于创建 `pwittrock/brodocs` Docker 镜像。它还尝试将镜像推送到 DockerHub,但是如果该步骤失败也没关系。只要镜像在本地,就可以成功生成代码。 + +```shell +make brodocs +``` + + + +确认 brodocs 镜像是否存在: + +```shell +docker images +``` + + + +输出显示 `pwittrock/brodocs` 是可用镜像之一: + +```shell +REPOSITORY TAG IMAGE ID CREATED SIZE +pwittrock/brodocs latest 999d34a50d56 5 weeks ago 714MB +``` + + + +## 运行文档生成代码 + + + +构建并运行文档生成代码。你可能需要以 root 用户运行命令: + +```shell +cd +make api +``` + + + +### 找到生成的文件 + + + +这两个文件是成功构建的产物。验证它们是否存在: + +* `/gen-apidocs/generators/build/index.html` +* `/gen-apidocs/generators/build/navData.js` + + + +## 将生成的文档复制到 kubernetes/website 仓库 + + + +前面的章节展示了如何编辑 Kubernetes 源文件,生成 OpenAPI 规范,然后生成用于发布的参考文档。 + + + +本章节介绍如何将生成的文档复制到 [kubernetes/website](https://github.com/kubernetes/website) 仓库。`kubernetes/website` 仓库中的文件发布在 [kubernetes.io](https://kubernetes.io) 网站上。特别是,生成的 `index.html` 文件发布在[这里](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)。 + + + +输入以下命令将生成的文件复制到 kubernetes/website 仓库的本地目录: + +```shell +make copyapi +``` + + + +进入 kubernetes/kubernetes 仓库的本地主目录,查看哪些文件已被修改: + +```shell +cd +git status +``` + + + +输出显示修改后的文件: + +```shell +On branch master +... + modified: docs/reference/generated/kubernetes-api/v1.9/index.html +``` + + + +在本例中,只修改了一个文件。回想一下,你生成了 `index.html` 和 `navData.js`。但显然生成的 `navata.js` 与 kubernetes/website` 仓库中已有的 `navData.js` 没有什么不同。 + + + +在 `` 目录下运行 `git add` 和 `git commit` 将提交修改。 + + + +将你的修改作为 [pull request](/docs/home/contribute/create-pull-request/) 提交到 [kubernetes/website](https://github.com/kubernetes/website) 仓库。跟踪你的 PR,并根据需要回应评审人的评论。继续跟踪你的 PR,直到它被合入。 + + + +在 PR 合入的几分钟后,你的修改将出现在[已发布的参考文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* [为 Kubernetes 组件和工具生成参考文档](/docs/home/contribute/generated-reference/kubernetes-components/) +* [为 kubectl 命令集生成参考文档](/docs/home/contribute/generated-reference/kubectl/) +* [为 Kubernetes 联邦 API 生成参考文档](/docs/home/contribute/generated-reference/federation-api/) + +{{% /capture %}} + + + diff --git a/content/zh/docs/contribute/generate-ref-docs/kubernetes-components.md b/content/zh/docs/contribute/generate-ref-docs/kubernetes-components.md new file mode 100644 index 0000000000000..8df429632cb06 --- /dev/null +++ b/content/zh/docs/contribute/generate-ref-docs/kubernetes-components.md @@ -0,0 +1,412 @@ +--- +title: 为 Kubernetes 组件和工具生成参考页面 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +本页面展示了如何使用 `update-imported-docs` 工具来为 [Kubernetes](https://github.com/kubernetes/kubernetes) 和 [Federation](https://github.com/kubernetes/federation) 仓库中的工具和组件生成参考文档。 + +{{% /capture %}} + +{{% capture prerequisites %}} + + + +* 你需要一个运行着 Linux 或 macOS 操作系统的机器。 + + + +* 你需要安装以下软件: + + * [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) + + * 1.9或更高版本的 [Golang](https://golang.org/doc/install) + + * [make](https://www.gnu.org/software/make/) + + * [gcc compiler/linker](https://gcc.gnu.org/) + + + +* 在环境变量中设置 `$GOPATH`。 + + + +* 你需要知道如何在一个 GitHub 项目仓库中创建一个 PR。一般来说,这涉及到创建仓库的一个分支。想了解更多信息,请参见[创建一个文档 PR](/docs/home/contribute/create-pull-request/)。 + +{{% /capture %}} + +{{% capture steps %}} + + + +## 下载两个仓库 + + + +如果你还没有下载过 `kubernetes/website` 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/website +``` + + + +确定 [kubernetes/website](https://github.com/kubernetes/website) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/website`。下文将该目录称为 ``。 + + + +如果你想对参考文档进行修改,但是你还没下载过 `kubernetes/kubernetes` 仓库,现在下载: + +```shell +mkdir $GOPATH/src +cd $GOPATH/src +go get github.com/kubernetes/kubernetes +``` + + + +确定 [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 仓库的本地主目录。例如,如果按照前面的步骤来获取该仓库,则主目录是 `$GOPATH/src/github.com/kubernetes/kubernetes`。下文将该目录称为 ``。 + +{{< note >}} + + +如果你只想生成参考文档,而不需要修改,则不需要手动下载 `kubernetes/kubernetes` 仓库。当你运行 `update-imported-docs` 工具时,它会自动克隆 `kubernetes/kubernetes` 仓库。 +{{< /note >}} + + + +## 编辑 Kubernetes 源码 + + + +Kubernetes 组件和工具的参考文档是基于 Kubernetes 源码自动生成的。如果想要修改参考文档,可以从修改 Kubernetes 源码中的一个或多个注释开始。在本地 kubernetes/kubernetes 仓库中进行修改,然后向 [github.com/kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) 的 master 分支提交 PR。 + + + +[PR 56942](https://github.com/kubernetes/kubernetes/pull/56942) 是一个对 Kubernetes 源码中的注释进行修改的 PR 示例。 + + + +跟踪你的 PR,并回应评审人的评论。继续跟踪你的 PR,直到它合入到 `kubernetes/kubernetes` 仓库的 master 分支中。 + + + +## 以 cherry-pick 方式将你的修改合入已发布分支 + + + +你的修改已合入 master 分支中,该分支用于开发下一个 Kubernetes 版本。如果你希望修改部分出现在已发布的 Kubernetes 版本文档中,则需要提议将它们以 cherry-pick 方式合入已发布分支。 + + + +例如,假设 master 分支正用于开发 Kubernetes 1.10 版本,而你希望将修改合入到已发布的 1.9 版本分支。相关的操作指南,请参见 [提议一个 cherry-pick 合入](https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md)。 + + + +跟踪你的 cherry-pick PR,直到它合入到已发布分支中。 + +{{< note >}} + + +提议一个 cherry-pick 合入,需要你有在 PR 中设置标签和里程碑的权限。如果你没有,你需要与有权限为你设置标签和里程碑的人合作完成。 +{{< /note >}} + + + +## update-imported-docs 概述 + + + +`update-imported-docs` 工具在 `kubernetes/website/update-imported-docs/` 目录下。它执行以下步骤: + + + +1. 克隆配置文件中指定的相关仓库。为了生成参考文档,默认情况下克隆的仓库是 `kubernetes-incubator/reference-docs` 和 `kubernetes/federation`。 +1. 在克隆出的仓库下运行命令来准备文档生成器,然后生成 Markdown 文件。 +1. 将生成的 Markdown 文件复制到配置文件中指定的 `kubernetes/website` 仓库的本地目录中。 + + + +当 Markdown 文件放入 `kubernetes/website` 仓库的本地目录中后,你就可以创建 [PR](/docs/home/contribute/create-pull-request/) 将它们提交到 `kubernetes/website`。 + + + +## 自定义配置文件 + + + +打开 `/update-imported-docs/reference.yml` 进行编辑。不要修改 `generate-command` 条目的内容,除非你了解它的作用,并且需要修改指定的已发布分支。 + +```shell +repos: +- name: reference-docs + remote: https://github.com/kubernetes-incubator/reference-docs.git + # This and the generate-command below needs a change when reference-docs has + # branches properly defined + branch: master + generate-command: | + cd $GOPATH + git clone https://github.com/kubernetes/kubernetes.git src/k8s.io/kubernetes + cd src/k8s.io/kubernetes + git checkout release-1.11 + make generated_files + cp -L -R vendor $GOPATH/src + rm -r vendor + cd $GOPATH + go get -v github.com/kubernetes-incubator/reference-docs/gen-compdocs + cd src/github.com/kubernetes-incubator/reference-docs/ + make comp +``` + + + +在 reference.yml 中,`files` 字段是 `src` 和 `dst` 字段的列表。`src` 字段指定生成的 Markdown 文件的位置,而 `dst` 字段指定将此文件复制到 `kubernetes/website` 仓库的本地目录的哪个位置。例如: + +```yaml +repos: +- name: reference-docs + remote: https://github.com/kubernetes-incubator/reference-docs.git + files: + - src: gen-compdocs/build/kube-apiserver.md + dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md + ... +``` + + + +注意,当有许多文件要从同一个源目录复制到同一个目标目录时,可以使用通配符给 `src` 赋值,而使用目录名给 `dst` 赋值。例如: + +```shell + files: + - src: gen-compdocs/build/kubeadm*.md + dst: content/en/docs/reference/setup-tools/kubeadm/generated/ +``` + + + +## 运行 update-imported-docs 工具 + + + +在检查与或自定义 `reference.yaml` 文件后,运行 `update-imported-docs` 工具: + +```shell +cd /update-imported-docs +./update-imported-docs reference.yml +``` + + + +## 在 kubernetes/website 中添加和提交修改 + + + +列出生成并准备合入到 `kubernetes/website` 仓库中的文件: + +``` +cd +git status +``` + + + +输出展示了新增和修改的文件。例如,输出可能如下所示: + +```shell +... + + modified: content/en/docs/reference/command-line-tools-reference/cloud-controller-manager.md + modified: content/en/docs/reference/command-line-tools-reference/federation-apiserver.md + modified: content/en/docs/reference/command-line-tools-reference/federation-controller-manager.md + modified: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md + modified: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md + modified: content/en/docs/reference/command-line-tools-reference/kube-proxy.md + modified: content/en/docs/reference/command-line-tools-reference/kube-scheduler.md +... +``` + + + +运行 `git add` 和 `git commit` 将提交上述文件。 + + + +## 创建 PR + + + +对 `kubernetes/website` 仓库创建 PR。跟踪你的 PR,并根据需要回应评审人的评论。继续跟踪你的 PR,直到它被合入。 + + + +在 PR 合入的几分钟后,你更新的参考主题将出现在[已发布文档](/docs/home/)中。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* [为 kubectl 命令集生成参考文档](/docs/home/contribute/generated-reference/kubectl/) +* [为 Kubernetes API 生成参考文档](/docs/home/contribute/generated-reference/kubernetes-api/) +* [为 Kubernetes 联邦 API 生成参考文档](/docs/home/contribute/generated-reference/federation-api/) + +{{% /capture %}} \ No newline at end of file diff --git a/content/zh/docs/contribute/intermediate.md b/content/zh/docs/contribute/intermediate.md new file mode 100644 index 0000000000000..82d42e8f4ef9d --- /dev/null +++ b/content/zh/docs/contribute/intermediate.md @@ -0,0 +1,1498 @@ +--- +title: 中级贡献 +slug: intermediate +content_template: templates/concept +weight: 20 +card: + name: contribute + weight: 50 +--- + +{{% capture overview %}} + + +本文假定你已经阅读并掌握了[开始贡献](/docs/contribute/start/)中介绍的内容, +想要了解更多关于贡献的内容。 + + +{{< note >}} +有些任务需要使用Git命令行客户端和其他工具。 +{{< /note >}} + +{{% /capture %}} + +{{% capture body %}} + + +现在,您已经熟悉了Kubernetes文档,并按照[开始贡献](/docs/contribute/start/)文章中介绍的方式进行了贡献, +您可能已经准备好做更多的工作。这些任务假设您已经或愿意获得以下主题领域的更深入的知识: + + +- Kubernetes概念 +- Kubernetes文档工作流 +- 在哪里和如何找到即将推出的Kubernetes功能的信息 +- 较强的研究能力 + + +这些任务不像初学者的任务那样是顺序的。没有人期望一个人会一直做所有的事情。 + +## 评审 pull request + + +通常,每周都会有一个特定的文档审核志愿者对[pull requests 和 issues](#triage-and-categorize-issues) +进行分类和审核。这个人就是本周的“PR 牧马人”。排班计划在[PR 牧马人排班](https://github.com/kubernetes/website/wiki/PR-Wranglers)维护。 +如果想要加入排班计划,需要参加每周的 SIG Docs 会议并志愿申请。 +尽管你不在本周的排班计划中,你也可以审核那些还未开始检视的PR。 + + +除了轮换之外,自动化系统(机器人)会根据修改的文件自动推荐相应的 approver 和 reviewer。 +PR作者应该遵循机器人的指导,这也有助于PR得到快速审查。 + + +我们希望尽快合并和发布pull requests。 +为了确保文档是准确的和最新的,每个PR都需要由理解内容的人以及具有编写优秀文档经验的人来评审。 + + +评审人员和批准人员需要提供可操作的和建设性的反馈,以保持贡献者的参与并帮助他们改进。 +有时候,帮助一个新的贡献者把他们的PR准备好合并比你自己重写它需要更多的时间, +但是从长远来看,当我们有不同的积极参与者时,这个项目会更好。 + + +在开始评审PR之前,请确保熟悉 [文档风格指南](/docs/contribute/style/style-guide/) +和 [行为准则](/community/code-of-conduct/)。 + + +### 找一个PR来评审 + + +要查看所有打开的PR,请转到GitHub仓库中的**Pull Requests**选项卡。 +当符合以下所有条件时,PR才有资格进行评审: + + +- 拥有 `cncf-cla:yes` 标签 +- 描述中没有WIP +- 没有包含`do-not-merge`字样的标签 +- 没有合并冲突 +- 基于正确的分支(通常为“master”,除非PR与某个未发布的功能相关) +- 没有被其他文档人员(或其他技术领域的评审人)评审,除非你被显式的请求参与评审。 + 需要说明的是,如果其他评审已经结束的情况下,你再留下很多新的意见,会让人感到沮丧,这适得其反。 + + +如果PR不符合合并的条件,请留下评论,让作者知道问题所在,并帮助他们解决问题。 +如果他们被告知并在几周或几个月内没有解决问题,最终他们的PR将被关闭而不会合并。 + + +如果您是新手,或者您没有太多的带宽,请寻找具有 `size/XS` 或 `size/S` 标记集的PR。 +大小由PR更改的行数自动设置。 + +#### 评审人员和批准人员 + + +Kubernetes 网站仓库与 Kubernetes 的一些代码仓库在涉及审核者和审批者角色时的操作方式不同。 +有关评审人员和批准人员职责的更多信息,请参见[参与](/docs/contribute/participating/)。 +这里只做一个概述。 + + +- 当评审人员以评审PR的技术准确性时,评审人员发表一个 `/lgtm` 评论表示技术上是无误的。 + + {{< note >}}如果你对技术准确性不确信,不要在涉及文档修改的PR中回复 `/lgtm`。 {{< /note >}} + +- 批准者审核有关文档修改的内容时,注重质量和相关规范(比如[风格规范](/docs/contribute/style/style-guide))。 + 只有在 [`OWNERS`](https://github.com/kubernetes/website/blob/master/OWNERS) 文件中列出的 + 人才可以批准PR。批准PR时,需要回复一个`/approved`评论。 + + +如果PR拥有来自Kubernetes社区的任何人的`/lgtm`评论和来自`sig-docs-maintainers`组的`/approved`评论, +只要它没有被hold并且作者已签署了CLA,PR就会被合并。 + + +### 审核PR + + + + +1. 阅读PR描述,并阅读任何附加的问题或链接,如果有的话。 + “快速评审”有时弊大于利,所以确保你有正确的知识来提供有意义的评审。 + +2. 如果其他人是审核这个PR的最佳人选,请通过添加`/assign @`的评论让他们知道。 + 如果你要求一个非文档人员进行技术评审,但仍然想从文档的角度来评审PR,那就继续吧。 + +3. 转到 **Files changed** 选项卡。查看所有的修改行。删除的内容具有红色背景,这些行也以 `-` 符号开头。 + 添加的内容具有绿色背景,这些行也以 `+` 符号开始。在一行中,实际修改的内容的背景颜色比该行的其余部分略深一些。 + + - 特别是如果PR使用复杂的格式或更改CSS、Javascript或其他站点范围内的元素,您可以使用PR预览网站。 + 转到 **Conversation** 选项卡,单击页面底部附近的 `deploy/netlify` 测试的 **Details** 链接。 + 默认情况下,它会在同一个浏览器窗口中打开,所以在一个新窗口中打开它,这样你就不会丢失你的部分评论。 + 切换回 **Files changed** 选项卡以继续您的审阅。 + - 确保PR符合文档[风格指南](/docs/contribute/style/style-guide/), + 如果不符合,请将作者链接到风格指南的相关部分。 + - 如果您对给定的更改有疑问、评论或其他反馈,请将鼠标悬停在一行上,然后单击出现的蓝白相间的 `+` 号。 + 键入您的评论并单击 **Start a review**。 + + - 如果你有更多的评论,请以同样的方式留下评论。 + - 按照惯例,如果您看到一个与PR的主要目的无关的小问题,比如一个打印错误或空格错误, + 您可以将它指出来,并在注释前加上nit:以便作者知道您认为它是无关紧要的。 + 他们仍然应该解决这个问题。 + - 当您查看完所有内容,或者没有任何评论时,回到页面顶部并单击 **Review changes**。 + 选择**Comment** 或**Request Changes**。添加评审摘要, + 并在评审摘要字段中另起一行添加适当的[Prow 命令](https://prow.k8s.io/command-help)。 + SIG Docs 遵循[Kubernetes代码审查流程](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md#the-code-review-process)。 + 您所有的意见将在一个单一的评论中发送给PR作者。 + + - 如果您认为PR已经准备好合并,请将文本 `/approve` 添加到摘要中。 + - 如果PR不需要额外的技术审查,也可以同时添加文本 `/lgtm` 。 + - 如果PR *确实* 需要额外的技术审查,使用 `/assign` + GitHub 用户名添加需要提供技术审查的人。 + 查看上面出现的 Markdown 文件中的`reviewers`字段,看看谁可以提供技术审阅。 + - 如果需要阻止PR被合并,加上 `/hold` ,就会设置 `do-not-merge/hold` 标签。 + - 如果PR没有冲突、有 `lgtm` 和 `approved` 标签且没有 `hold` 标签,它就会自动合并。 + - 如果PR拥有 `lgtm` 和 `approved` 后再有新的变更,那么这些标签会自动清除。 + + PR中可能用到的命令,参阅 + [斜线命令列表](https://prow.k8s.io/command-help)。 + + - 如果您以前选择了**Request changes** ,并且PR作者已经处理了您的关注点, + 那么您可以在**Files changed** 选项卡或 **Conversation** 选项卡底部更改您的审阅状态。 + 确保添加 `/approve` 标签,并在必要时指派技术审阅人员,以便合并PR。 + + +### 提交到别人的PR + + +留下评论是有帮助的,但有时你需要把自己的想法融入到其他人的PR中,而不仅仅是留下评论。 + + +除非对方明确要求你“接手”,或者你想重新建立一个长期被抛弃的PR,否则不要急于“接手”。 +虽然短期内这样做可能更快,但会剥夺这个人做出贡献的机会。 + + +您的做法(接手)取决于您是需要编辑已经在PR范围内的文件,还是PR尚未触及的文件。 + + +如果以下任何一件事是符合的,你就不能提交到某人的PR: + + +- 如果PR作者将他们的分支直接推入https://github.com/kubernetes/website/ repository, + 那么只有具有push访问权限的审阅者才能提交到他们的PR中。 +- 如果PR作者明确禁止审批者进行编辑,那么除非他们更改此设置,否则您无法提交到他们的PR中。 + + +#### 文件已在PR中修改 + + +这个方法使用GitHub UI。如果您愿意,您可以使用命令行,即使您想更改的文件是PR的一部分,如果您更愿意这样工作的话。 + + + +1. 点击 **Files changed** 选项卡。 +2. 向下找到你想要编辑的文件,点击铅笔图标。 +3. 修改并在下面添加提交记录,点击 **Commit changes**。 + + +您的提交现在被推送到PR对应的分支(可能在作者的分支上), +在PR中,您的更改反映在 **Files changed** 选项卡中。 +留下评论,让PR作者知道你修改了PR。 + + +如果作者使用命令行而不是GitHub UI来处理这个PR,那么在处理PR之前, +他们需要获取fork的更改并将本地分支重新建立在fork中的分支上。 + +#### 如果文件没有被PR修改 + + +如果需要更改尚未包含在PR中的文件,则需要使用命令行。 +如果您喜欢使用这个方法而不喜欢使用GitHub UI,那么您总是可以使用这个方法。 + + +1. + 获取作者的fork的URL。你可以在**Conversation** 标签的底部找到它。 + 查找文本 **Add more commits by pushing to** 。 + 这个短语后面的第一个链接是到分支的,第二个链接是到fork的。 + 复制第二个链接。稍后会用到分支的名称。 + +2. + 要给远程设置一个名称(比如作者的GitHub用户名),然后使用以下语法添加远程: + + ``` + git remote add + ``` + +3. + 获取远程。这不会更改任何本地文件,但会更新克隆的远程对象的概念(如分支和标记)及其当前状态。 + + ``` + git remote fetch + ``` + +4. + 拉取远程分支。如果已经有同名的本地分支,则此命令将失败。 + + ``` + git checkout + ``` + +5. + 进行更改,使用 `git add` 添加更改,然后提交更改。 + +6. + 将您的更改推到作者的远程。 + + ``` + git push + ``` + +7. + 回到GitHub UI并刷新PR。给PR作者留言,让他们知道你修改了PR。 + + +如果作者使用命令行而不是GitHub UI来处理这个PR,那么在处理PR之前, +他们需要获取fork的更改并将本地分支重新建立在fork中的分支上。 + + +## 使用本地克隆 + + +对于需要多个文件的更改,或者涉及创建新文件或移动文件的更改, +使用本地Git克隆比依赖GitHub UI更有意义。 +这些指令使用git命令,并假设您已经在本地安装了它。 +您可以将它们调整为使用本地图形化Git客户机。 + + +### 克隆仓库 + + +对于处理Kubernetes文档的每个物理机,只需要克隆存储库一次。 + + + +1. 在终端中使用 `git clone` 来克隆仓库。你不需要指定任何证书。 + + ``` + git clone https://github.com/kubernetes/website + ``` + 新目录 `website` 会在当前目录中创建并包含该仓库的内容。 + +2. 进入 `website` 目录,将默认的 `origin` 重命名为远端 `upstream`。 + + ``` + cd website + + git remote rename origin upstream + ``` + +3. 如果还没有这样做,请在GitHub上创建存储库的分支。 + 在您的web浏览器中,访问[https://github.com/kubernetes/website](https://github.com/kubernetes/website) + 并单击Fork按钮。几秒钟后,您将被重定向到您的fork的URL,它通常类似于`https://github.com//website` , + 除非您已经有一个名为 `website`的存储库。复制这个网址。 + +4. 在你的fork中增加另一个远端 `origin`: + + ``` + git remote add origin + ``` + + +### 使用本地仓库 + + +在本地存储库上启动新的工作单元之前,您需要确定将工作基于哪个分支。 +答案取决于你在做什么,但是下面的指导方针是适用的: + + +- 对于现有内容的一般改进,可以从 `master` 开始。 +- 对于关于Kubernetes发布版本中已经存在的特性的新内容,请从 `master` 开始。 +- 对于多个SIG Docs贡献者将协作的长期工作,例如内容重组,使用为该工作创建的特定功能分支。 +- 对于与即将发布但尚未发布的Kubernetes版本相关的新内容,请使用为该Kubernetes版本创建的预发布特性分支。 + + +更多指导,请参考[选择分支](/docs/contribute/start/#choose-which-git-branch-to-use)。 + + +在您决定要使用哪个分支之后(或者用Git术语来说,基于它), +使用以下工作流来确保您的工作基于该分支的最新版本。 + + +1. + 拉取 `upstream` 和 `origin` 远端。 + 这将更新您对这些分支所包含内容的本地概念,但不会更改您的本地分支。 + + ``` + git fetch upstream + git fetch origin + ``` + +2. + 基于你选择的分支创建一个新的跟踪分支。以你使用master为例: + + ``` + git checkout -b upstream/master + ``` + + + 新分支基于 `upstream/master`, 而不是你本地的 `master`。它跟踪 `upstream/master`。 + +3. + 在检出的分支上使用编辑器修改。 + 你可以随时使用 `git status` 命令来查看你的更改。 + + +4. + 当您准备提交pull request时,提交您的更改。 + 首先使用git status查看需要向变更集中添加哪些更改。 + 有两个重要的部分:`Changes staged for commit`和`Changes not staged for commit`。 + 如果您希望将后一节中显示的`modified` 或 `untracked` 文件添加到提交中,你需要使用`git add`。 + + ``` + git add example-file.md + ``` + + + 当所有文件准备好时,使用 `git commit` 命令提交: + + ``` + git commit -m "Your commit message" + ``` + + {{< note >}} + 不要在提交消息中引用GitHub issue 或 PR(通过ID或URL)。如果您这样做了,那么每当提交出现在新的Git分支中时,就会导致该issue或PR获得通知。稍后,您可以在GitHub UI中链接问题并将请求拉到一起。 + {{< /note >}} + +5. + 您还可以选择使用hugo命令在本地暂存站点来测试您的更改。[时间看本地更改](#view-your-changes-locally)。 + 您还可以在提交PR后查看更改。 + +6. + 在创建包含本地提交的PR之前,需要将分支推到fork,也就是`origin`端点。 + + ``` + git push origin + ``` + + 从技术上讲,您可以从push命令中省略分支名称,但是这种情况下的行为取决于您使用的Git版本。 + 如果包含分支名称,结果将更加可重复。 + + +7. + 此时,如果您在web浏览器中访问https://github.com/kubernetes/website, GitHub会检测到您将一个新的分支推送到您的fork,并提供创建一个pull请求。填写pull request模板。 + + - 标题不应超过50个字符,并总结更改的意图。 + - + 长表单描述应该包含关于修复的更多信息,如果PR修复了GitHub issue, + 则应该包含类似`Fixes #12345`这样的行。 + 这将导致在合并PR时自动关闭该问题。 + - + 您可以添加标签或其他元数据并分配审阅人员。有关语法,请参见[分类和分类问题](#triage-and-categorize-issues)。 + + 点击 **Create pull request** + +8. + 几个自动化测试将运行与您所应用的更改的网站状态。 + 如果任何测试失败,请单击**Details**链接获取更多信息。 + 如果Netlify测试成功完成,它的**Details**链接将转到Kubernetes网站的阶段性版本, + 其中应用了您的更改。 + 这是审阅人员检查更改的方式。 + +9. + 如果您注意到需要进行更多的更改,或者评审人员给了您反馈,请在本地处理反馈, + 然后再次重复步骤4 - 6,创建一个新的提交。新的提交被添加到您的pull请求中, + 测试再次运行,包括Netlify。 + +10. + 如果审查员将更改添加到您的pull请求中,您需要从fork获取这些更改,然后才能添加更多的更改。 + 假设您的分支当前已签出,请使用以下命令来完成此操作。 + + ``` + git fetch origin + git rebase origin/ + ``` + + 在rebasing之后,您需要添加`-f`标志来强制推送分支。 + + ``` + git push -f origin + ``` + +11. + 如果其他人的更改合并到您工作所基于的分支中,并且您对相同文件的相同部分进行了更改, + 则可能会发生冲突。如果pull请求显示有需要解决的冲突,您可以使用GitHub UI解决它们, + 或者在本地解决它们。 + + 首先执行第10步,确保你的fork仓库与你本地分支一致。 + + + 接着,拉取 `upstream` 并 rebase 你的分支。 + + ``` + git fetch upstream + git rebase upstream/master + ``` + + + 如果存在Git无法自动解决的冲突,可以使用`git status`命令查看冲突文件。 + 对于每个冲突文件,编辑它并查找冲突标记`>>>`,`<<<`,and `===`。 + 解决冲突并删除冲突标记。然后使用`git add `, + 并使用`git rebase --continue`继续将更改添加到更改集中。 + 当所有提交都已应用,并且没有更多冲突时,`git status`将显示您不在rebase中, + 并且不需要提交任何更改。此时,强制将分支推到fork, pull请求应该不再显示任何冲突。 + + +如果您在解决冲突方面遇到困难,或者您被与pull请求相关的任何其他事情卡住, +请在`#sig-docs` Slack通道或[kubernet-sig-docs邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)中寻求帮助。 + + +### 本地查看更改 + + +如果您还没有准备好创建一个pull请求, +但是您希望看到您的更改是什么样子的, +那么您可以构建并运行一个docker映像来生成所有文档并在本地提供它。 + + +1. 本地构建镜像: + + ``` + make docker-image + ``` + +2. `kubernetes-hugo` 镜像构建完成后,可以构建并启动网站: + + ``` + make docker-serve + ``` + +3. 在浏览器地址栏输入 `localhost:1313`。Hugo将监视文件系统的更改,并根据需要重新构建站点。 + +4. 如果想停掉本地Hugo实例,只需要在命令行中键入`Ctrl+C`来关闭命令行窗口。 + + +或者,您可以在您的开发机器上安装并使用hugo命令: + +1. + [安装 Hugo](https://gohugo.io/getting-started/installing/) 版本 {{< hugoVersion >}} 或更新版本. + +2. + 在终端中,转到您克隆的Kubernetes文档的根目录,并输入以下命令: + + ``` + hugo server + ``` + +3. + 在浏览器地址栏中输入 `localhost:1313`。 + +4. + 如果想停掉本地Hugo实例,只需要在命令行中键入`Ctrl+C`来关闭命令行窗口。 + + +## 问题归类 + + +在任何给定的一周内,一个特定的文档审批者会自愿对pull请求和问题进行初步分类和审查。 +要进入这个名单,参加每周的团体文档会议和志愿者。 +即使你不在这周的时间表上,你仍然可以审核PR。 + + +SIG文档人员只负责对文档问题进行分类和分类。一般的网站问题也归档在`kubernetes/website` 资源库中。 + + +当你对一个问题进行分类时: + + +- 评估这个问题是否有价值。有些问题可以通过回答问题或向作者指出资源来迅速解决。 +- 如果问题没有足够的细节可以采取行动,或者模板没有填好,询问作者更多的信息。 +- 向问题添加标签(有时称为标签)、项目或里程碑。SIG文档团队并没有大量使用项目和里程碑。 +- 根据您的判断,对某个问题拥有所有权并为其提交PR(特别是如果它是快速的或与您已经在做的工作相关的)。 + + +如果你针对问题分类有疑问,请在Slack `#sig-docs` 频道或 +[kubernetes-sig-docs 邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) +中询问。 + + +### 有关标签的更多信息 + + +这些准则并非一成不变,可能会发生变化。 + + +- 一个问题可以有多个标签。 +- 一些标签使用斜杠符号进行分组,可以将其视为“子标签”。例如,`sig/`存在许多标签,例如 `sig/cli` 和 `sig/api-machinery`。 +- 系统会根据问题所涉及文件中的元数据,问题注释中使用的斜杠命令或问题文本中的信息,自动添加一些标签。 +- 由负责问题分类的人员(或报告问题的人员,如果他们是SIG文档批准者)手动添加一些标签。 + - `Actionable`:似乎有足够的信息可以解决或解决此问题。 + - `good first issue`:Kubernetes或SIG Docs经验有限的人也有可能可以解决此问题。 + - `kind/bug`, `kind/feature`, and `kind/documentation`: + 如果提出问题的人未正确填写模板,则可能不会自动分配这些标签。 + 错误是现有内容或功能的问题,功能是对新内容或功能的请求。`kind/documentation`标签当前未使用。 + - 优先级标签:定义问题的相对严重性。 + 这些并没有在[Kubernetes贡献者指导](https://github.com/kubernetes/community/blob/master/contributors/guide/issue-triage.md#define-priority)中, + 可以是一个P1,P2或者P3。 +- 要添加标签,如果您是Sig Docs批准者,则可以使用GitHub的Labels小部件。Kubernetes组织的任何人都可以通过添加评论来添加标签/label 。标签必须已经存在。如果您尝试添加不存在的标签,该命令将被静默忽略。 + + +### 优先级 + + +问题的优先级会影响问题的解决速度。对于文档,以下是设置问题优先级的准则: + +#### P1 + + +- 影响超过1页的主要内容错误 +- 大量访问的页面上的代码示例损坏 +- “入门”页面上的错误 +- 众所周知或广为宣传的客户痛点 +- 自动化问题 + +#### P2 + + + + +- 不经常使用的示例代码损坏 +- 页面流量过大的次要内容问题 +- 流量较低的页面上的主要内容问题 + + +#### P3 + + +- 错别字和损坏的链接 +- 文档功能要求 +- “有了更好(没有也问题不大)”项目 + + +### 处理特殊问题类型 + + +我们经常遇到以下类型的问题,有必要记录如何处理它们。 + + +#### 重复的问题 + + +如果单个问题可以解决一个或多个问题,则应将该问题合并为一个问题。 +您应该决定哪个问题保持打开状态(或打开一个新问题),移植所有相关信息,链接相关问题, +并关闭描述同一问题的所有其他问题。只处理一个问题将有助于减少混乱并避免重复处理同一问题。 + + +#### 无效链接问题 + + +根据报告无效链接的位置,需要采取不同的措施来解决此问题。 +API和Kubectl文档中的无效链接是自动化问题,应分配为P1,直到可以完全解决该问题为止。 +所有其他无效链接都是需要手动修复的问题,可以将其分配为P3。 + + +#### 博客问题 + + +随着时间的流逝,Kubernetes博客条目预计会过时, +因此我们仅保留不到一年的博客条目。 +如果某个问题与存在超过一年的博客条目有关,则应将其关闭而不进行修复。 + + +#### 支持请求或代码错误报告 + + +相反,为文档带来的一些问题是底层代码的问题, +或者在某些内容(例如教程)不起作用时请求帮助。 +对于与文档无关的问题,请关闭issue并指示请求者正确的支持场所(Slack,Stack Overflow), +并在适当的地方针对具有功能缺陷的问题提出问题(可以从kubernetes/kubernetes开始)。 + + +对支持请求的响应示例: + +```none +This issue sounds more like a request for support and less +like an issue specifically for docs. I encourage you to bring +your question to the `#kubernetes-users` channel in +[Kubernetes slack](http://slack.k8s.io/). You can also search +resources like +[Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes) +for answers to similar questions. + +You can also open issues for Kubernetes functionality in + https://github.com/kubernetes/kubernetes. + +If this is a documentation issue, please re-open this issue. +``` + + +示例代码错误报告响应: + +```none +This sounds more like an issue with the code than an issue with +the documentation. Please open an issue at +https://github.com/kubernetes/kubernetes/issues. + +If this is a documentation issue, please re-open this issue. +``` + + +## 记录新功能 + + +每个主要的Kubernetes版本都包含新功能,其中许多功能至少需要少量文档才能向人们展示如何使用它们。 + + +通常,负责功能的SIG负责对`kubernetes/website`存储库的相应release分支发起PR, +提交该功能的文档草稿 ,并且由SIG Docs团队中的某人提供编辑反馈或直接编辑草稿。 + + +要了解即将发布的功能,请参加每周一次的sig-release会议 +(请参阅[社区](https://kubernetes.io/community/)页面以获取即将举行的会议, +并在[kubernetes/sig-release](https://github.com/kubernetes/sig-release/) 存储库中监视特定于发行版的文档。 +每个发行版在[/sig-release/tree/master/releases/](https://github.com/kubernetes/sig-release/tree/master/releases) + 目录下都有一个子目录。每个子目录包含一个发布计划,一个发布说明草稿以及一个列出发布团队中每个人的文档。 + + +- 发布时间表包含与发布有关的所有其他文档,会议,会议记录和里程碑的链接。 + 它还包含有关该发行版的目标和时间表的信息,以及此发行版的任何特殊流程。 + 在文档底部附近,定义了几个与发布相关的术语。 + + 本文档还包含**Feature tracking sheet**的链接,这是查找排定要发布的所有新功能的正式方法。 + +- 发布团队文档列出了负责每个发布角色的人员。 + 如果不清楚要与谁谈论某个特定功能或问题,请参加发布会议询问您的问题, + 或者与发布负责人联系,以便他们可以重定向您。 +- 发行说明草稿是了解更多有关特定功能,更改,不推荐使用以及更多有关发行版本的好地方。 + 该内容要到发布周期的后期才能最终确定,因此请谨慎使用。 + + +#### 功能跟踪表 + + +给定Kubernetes版本的功能跟踪表 列出了计划发布的每个功能。 +每个订单项都包含功能名称,功能主要GitHub问题的链接,其稳定性级别(Alpha,Beta或Stable), +SIG和负责实施此功能的人员,是否需要文档,发布说明草稿功能,以及是否已合并。请记住以下几点: + + +- Beta和稳定功能通常比Alpha功能具有更高的文档优先级。 +- 很难测试(因此要文档记录)尚未合并的功能,或者至少在其PR中被认为功能完整的功能。 +- 确定某个功能是否需要文档是一个手动过程,并且仅仅因为某个功能未标记为需要文档并不意味着它就不需要它们。 + + +### 记录功能 + + +如上所述,新功能的草案内容通常由负责实施新功能的SIG提交。 +这意味着您的角色可能更像是给定功能的牧羊人角色。 + + +选择要记录/跟踪的功能后,请在 `#sig-docs` Slack频道, +每周一次的sig-docs会议中或直接在功能SIG提交的PR上询问有关功能。 +如果得到批准,则可以使用[提交到别人的PR](#commit-into-another-persons-pr) +中介绍的技术来编辑 PR。 + + +如果您需要编写新主题,则以下链接很有用: + + +- [撰写新主题](/docs/contribute/style/write-new-topic/) +- [使用页面模板](/docs/contribute/style/page-templates/) +- [文档样式指南](/docs/contribute/style/style-guide/) + + +SIG成员记录了新功能 + + +如果您是Kubernetes开发新功能的SIG成员,则需要一并更新SIG文档, +以确保在发布该功能时及时记录了您的功能。 +查看 [功能跟踪电子表格](https://github.com/kubernetes/sig-release/tree/master/releases), + 或在 #sig-release Slack频道中查看验证计划详细信息和截止日期。 + 与文档相关的一些截止日期是: + + +- **文档截止期限-打开占位PR** :针对`kubernetes/website`仓库中的`release-X.Y`分支提交一个PR, + 稍作修改(占位),稍后您将继续修改。使用Prow命令`/milestone X.Y`将PR分配给相关的里程碑。 + 这会提醒管理此版本的文档人员功能文档即将发布。 + 如果您的功能不需要任何文档更改,请在#sig-release Slack频道中说一下, + 以确保sig-release团队知道这一点。 + 如果该功能确实需要文档,但未创建PR,则该功能可能已从里程碑中删除。 +- **文档截止日期-PR审核**:您的PR现在需要包含功能文档的初稿。不必担心格式或修饰。 + 只需描述该功能的用途以及使用方法即可。管理发行版的文档人员将与您合作,使内容成形以进行发布。 + 如果您的功能需要文档且未收到第一稿内容,则该功能可能已从里程碑中删除。 +- **文档完成-PR已审核,准备合并**:如果您的PR尚未在`release-X.Y`此期限之前合并到分支中, + 请与管理发行版的文档人员一起合作帮助它合入。 + 如果您的功能需要文档且文档尚未准备好,该功能可能会从里程碑中删除。 + + +如果您的功能是Alpha功能并且由[功能开关](/docs/reference/command-line-tools-reference/feature-gates/) +控制,请确保将其作为PR的一部分添加到功能开关。 +如果您的功能要移出Alpha,请确保将其从该文件中删除。 + + +## 贡献其他仓库 + + +该Kubernetes项目包含超过50个仓库。 +这些存储库中许多都包含可以视为文档的代码或内容,例如面向用户的帮助文本,错误消息, +API参考中的面向用户的文本,甚至是代码注释。 + + +如果您看到文本并且不确定其来源,则可以在Kubernetes组织级别使用GitHub的搜索工具在所有存储库中搜索该文本。 +这可以帮助您确定将问题或PR提交到哪里。 + + +每个存储库可能都有自己的流程和过程。 +在您提交的问题或提交PR,查看存储库的`README.md`,`CONTRIBUTING.md`以及 `code-of-conduct.md`。 + + +大多数存储库使用issue和PR模板。 +浏览一些未解决的问题和PR,以了解该团队的流程。 +提交问题或PR时,​​请确保尽可能详细地填写模板。 + + +## 本地化内容 + + +Kubernetes文档首先是用英语编写的,但是我们希望人们能够使用他们选择的语言来阅读它。 +如果您愿意用另一种语言编写,尤其是在软件领域,则可以帮助本地化Kubernetes文档 +或提供有关现有本地化内容的反馈。 +请参阅[本地化](/docs/contribute/localization/) , +并在[kubernetes-sig-docs邮件列表][kubernetes-sig-docs mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) #sig-docs上询问,或者在Slack上询问是否有帮助的兴趣。 + + +### 参与本地化工作 + + +请遵循以下准则来使用本地化内容: + + +- 将PR限制为一种语言。 + + 每种语言都有其自己的审阅者和批准者。 + +- 审阅者,请验证PR是否仅对一种语言进行了更改。 + + 如果PR包含对一种以上源语言的更改,请PR贡献者为每种语言打开单独的PR。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +如果您熟悉本主题中讨论的所有任务,并且想与Kubernetes文档小组进行更深入的接触, +请阅读[高级文档贡献者](/docs/contribute/advanced/)主题。 +{{% /capture %}} diff --git a/content/zh/docs/contribute/localization.md b/content/zh/docs/contribute/localization.md new file mode 100644 index 0000000000000..18cb55461165c --- /dev/null +++ b/content/zh/docs/contribute/localization.md @@ -0,0 +1,528 @@ +--- +title: 本地化 Kubernetes 文档 +content_template: templates/concept +approvers: +- chenopis +- zacharysarah +- zparnold +--- + + + +{{% capture overview %}} + + + +Kubernetes 文档库有多种语言: + + + +- 英语 +- 中文 +- 日语 +- 韩语 + + + +我们鼓励你添加新的[本地化](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/)! + +{{% /capture %}} + + +{{% capture body %}} + + + +## 入门 + + + +本地化必须满足工作流(*如何*本地化)和输出(本地化*内容*)的一些要求。 + + + +要添加 Kubernetes 文档库的新的本地化,你需要修改[网站配置](#modify-the-site-configuration) 和[目录结构](#add-a-new-localization-directory)来更新网站。然后你就可以开始[翻译文档](#translating-documents)了! + +{{< note >}} + + +本地化相关的[拉取请求](../create-pull-request) 示例,请参见向 Kubernetes 文档库 [Kubernetes website 仓库](https://github.com/kubernetes/website) 合入韩语本地化的[这个拉取请求](https://github.com/kubernetes/website/pull/8636)。 +{{< /note >}} + + + +让 Kubernetes SIG Docs 知道你对创建本地化感兴趣!加入 [SIG Docs Slack channel](https://kubernetes.slack.com/messages/C1J0BPD2M/)。我们很乐意帮助你快速上手并回答你的任何问题。 + + + +所有本地化团队必须使用自身的资源独立工作。我们很高兴支持你的工作,但无法为你翻译。 + + + +### 克隆仓库并创建分支 + + + +首先,在 [kubernetes/website](https://github.com/kubernetes/website) 中[创建你自己的分支](https://help.github.com/articles/fork-a-repo/)。 + + + +然后,克隆 website 仓库并通过 `cd` 命令进入 website 目录: + +```shell +git clone https://github.com/kubernetes/website +cd website +``` + +{{< note >}} + + +`k/website` 的贡献者必须[创建一个分支](/docs/contribute/start/#improve-existing-content),从创建拉取请求。对于本地化,我们还要求: + + + +1. 团队审批者直接从 https://github.com/kubernetes/website 新建开发分支。 +2. 本地化贡献者创建分支进行工作,其分支基于当前的开发分支。 + + + +这是因为本地化项目是在长期进行的分支上的协同工作,类似于 Kubernetes 发布周期的开发分支。有关本地化拉取请求,请参见[“分支策略”](#branching-strategy)。 +{{< /note >}} + + + +### 找到两个字母的语言代码 + + + +有关本地化的两个字母的国家代码,请参考 [ISO 639-1 标准](https://www.loc.gov/standards/iso639-2/php/code_list.php)。例如,德语的两个字母代码是 `de`。 + +{{< note >}} + + +这些说明遵循 [ISO 639-1](https://www.loc.gov/standards/iso639-2/php/code_list.php) 语言代码标准,以德语(`de`)为例。 + + + +目前没有针对德语的 Kubernetes 本地化,但欢迎你创建一个! +{{< /note >}} + + + +### 修改网站配置 + + + +Kubernetes 网站使用 Hugo 作为其 web 框架。网站的 Hugo 配置位于 [`config.toml`](https://github.com/kubernetes/website/tree/master/config.toml) 文件中。要支持新的本地化,你需要修改 `config.toml`。 + + + +将新语言的配置块添加到 `config.toml` 中现有的 `[languages]` 块下。例如,德语块如下所示: + +```toml +[languages.de] +title = "Kubernetes" +description = "Produktionsreife Container-Verwaltung" +languageName = "Deutsch" +contentDir = "content/de" +weight = 3 +``` + + + +为块分配 `weight` 参数时,请查找权重最大的语言块,并对该值加 1。 + + + +有关 Hugo 多语言支持的更多信息,请参见 “[多语言模式](https://gohugo.io/content-management/multilingual/)”。 + + + +### 创建新的本地化目录 + + + +将特定语言的子目录添加到仓库中的 [`content`](https://github.com/kubernetes/website/tree/master/content) 目录中。例如,德语的两个字母代码是 `de`: + +```shell +mkdir content/de +``` + + + +### 添加本地化自述文件 + + + +要指导其他本地化贡献者,请将新的 [`README-**.md`](https://help.github.com/articles/about-readmes/) 添加到 k/website 的顶层,其中 `**` 是两个字母的语言代码。例如,德语的自述文件是 `README-de.md`。 + + + +在本地化的 `README-**.md` 文件中为本地化贡献者提供指导。包括 `README.md` 中包含的相同信息以及: + + + +- 本地化项目的联系人 +- 任何特定于本地化的信息 + + + +创建本地化的自述文件后,请在主英文文件中添加指向该文件的链接,[`README.md`'s Localizing Kubernetes Documentation],并以英文包含联系信息。你可以提供 GitHub ID、电子邮箱、[Slack channel](https://slack.com/) 或其他联系方式。 + + + +## 翻译文档 + + + +本地化*所有* Kubernetes 文档是一项艰巨的任务。从小做起,循序渐进。 + + + +所有本地化至少必须包括: + + + +描述 | 网址 +-----|----- +主页 | [所有标题和副标题网址](/docs/home/) +安装 | [所有标题和副标题网址](/docs/setup/) +教程 | [Kubernetes 基础](/docs/tutorials/kubernetes-basics/), [Hello Minikube](/docs/tutorials/stateless-application/hello-minikube/) +网站字符串 | [新的本地化 TOML 文件中的所有网站字符串](https://github.com/kubernetes/website/tree/master/i18n) + + + +翻译后的文档必须保存在自己的 `content/**/` 子目录中,否则将遵循与英文源相同的 URL 路径。例如,要准备将 [Kubernetes 基础](/docs/tutorials/kubernetes-basics/) 教程翻译为德语,请在 `content/de/` 文件夹下创建一个子文件夹并复制英文源: + +```shell +mkdir -p content/de/docs/tutorials +cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md +``` + + + +本地化相关的[拉取请求](../create-pull-request) 示例,请参见向 Kubernetes 文档库 [Kubernetes website 仓库](https://github.com/kubernetes/website) 合入韩语本地化的[这个拉取请求](https://github.com/kubernetes/website/pull/10471)。 + + + +### 源文件 + + + +本地化必须使用最新版本的英文文件作为其源。最新版本是 **{{< latest-version >}}**。 + + + +要查找最新版本的源文件,请执行以下操作: + + + +1. 导航到 Kubernetes website 仓库,网址为 https://github.com/kubernetes/website。 +2. 选择 `release-1.X` 分支作为最新版本。 + + + +最新版本是 **{{< latest-version >}}**,所以最新的发布分支是 [`{{< release-branch >}}`](https://github.com/kubernetes/website/tree/{{< release-branch >}})。 + + + +### i18n 中的网站字符串/ + + + +本地化必须在新的语言特定文件中包含 [`i18n/en.toml`](https://github.com/kubernetes/website/blob/master/i18n/en.toml) 的内容。以德语为例:`i18n/de.toml`。 + + + +将新的本地化文件添加到 `i18n/`。例如德语 (`de`): + +```shell +cp i18n/en.toml i18n/de.toml +``` + + + +然后转换每个字符串的值: + +```TOML +[docs_label_i_am] +other = "ICH BIN..." +``` + + + +本地化网站字符串允许你自定义网站范围的文本和特性:例如,每个页面页脚中的合法版权文本。 + + + +## 项目组织 + + + +### 联系 SIG Docs 主席 + + + +开始新的本地化时,请联系 Kubernetes [SIG Docs](https://github.com/kubernetes/community/tree/master/sig-docs#chairs) 中的主席之一。 + + + +### 维护者 + + + +每个本地化存储库必须提供自己的维护人员。维护人员可以来自单个组织或多个组织。只要可能,本地化的拉取请求应该由来自不同组织的评审者批准,而不是由翻译人员批准。 + + + +本地化必须至少提供两个维护人员。(不能评审和批准自己的工作。) + + + +### 分支策略 + + + +因为本地化项目是高度协同的工作,所以我们鼓励团队基于共享的开发分支工作。 + + + +在开发分支上协作: + + + +1. 团队成员新建一个开发分支,通常通过在 https://github.com/kubernetes/website 上针对源分支新建一个拉取请求。 + + + + 我们推荐以下分支命名方案: + + `dev--.` + + + + 例如,一个德语本地化团队的审批者基于 Kubernetes v1.12 版本的源分支直接新建了 k/website 仓库的开发分支 `dev-1.12-de.1`。 + + + +2. 个人贡献者基于开发分支新建特性分支。 + + + + 例如,一个德国贡献者新建了一个拉取请求,并从 `username:local-branch-name` 更改了 `kubernetes:dev-1.12-de.1`。 + + + +3. 审批者审批功能分支并将其合入到开发分支中。 + + + +4. 审批者定期将开发分支合并到其源分支。 + + + +根据需要重复步骤 1-4,直到完成本地化工作。例如,随后的德语开发分支将是:`dev-1.12-de.2`、`dev-1.12-de.3`,等等。 + + + +团队必须将本地化内容合入到发布分支中,该发布分支也正是内容的来源。例如,源于 {{< release-branch >}} 的开发分支必须基于 {{< release-branch >}}。 + + + +审批者必须通过使开发分支与源分支保持最新并解决合并冲突来维护开发分支。开发分支的存在时间越长,通常需要的维护工作就越多。考虑定期合并开发分支并新建分支,而不是维护一个运行非常长的开发分支。 + + + +虽然只有审批者可以合入拉取请求,但任何人都可以为新的开发分支新建拉取请求。不需要特殊权限。 + + + +有关基于克隆或直接从仓库开展工作的更多信息,请参见 ["fork and clone the repo"](#fork-and-clone-the-repo)。 + + + +### 上游贡献 + + + +Sig Docs 欢迎[上游贡献和更正](/docs/contribute/intermediate#localize-content) 到英文源。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +一旦 l10n 满足工作流和最小输出的要求,SIG docs 将: + + + +- 在网站上启用语言选择 +- 通过[云原生计算基金会](https://www.cncf.io/) (CNCF) 渠道,包括 [Kubernetes blog](https://kubernetes.io/blog/),来宣传本地化的可用性。 + +{{% /capture %}} diff --git a/content/zh/docs/contribute/participating.md b/content/zh/docs/contribute/participating.md new file mode 100644 index 0000000000000..dce311e5372e5 --- /dev/null +++ b/content/zh/docs/contribute/participating.md @@ -0,0 +1,518 @@ +--- +title: 参与到 SIG Docs +content_template: templates/concept +card: + name: contribute + weight: 40 +--- + +{{% capture overview %}} + + +SIG Docs 是 Kubernetes 项目中的一个 [special interest groups](https://github.com/kubernetes/community/blob/master/sig-list.md), +总的来说,它负责编写、更新和维护 Kubernetes 文档。 + + +SIG Docs 欢迎所有贡献者提供内容和检视。任何人可以提交拉取请求(PR), +欢迎对文档内容提交 issue 和 对正在进行中的 PR 进行评论。 + + +在 SIG Docs,你可以成为 [member](#members)、[reviewer](#reviewers) 或者 [approver](#approvers)。 +这些角色拥有更高的权限,并且需要承担批准和提交更改的责任。 +有关Kubernetes社区中的成员如何工作的更多信息,请参见[community-membership](https://github.com/kubernetes/community/blob/master/community-membership.md)。 +本文档的其余部分概述了这些角色在 SIG Docs 中发挥作用的一些独特方式, +SIG Docs 负责维护 Kubernetes 最面向公众的方面之一—— Kubernetes 网站和文档。 +{{% /capture %}} + +{{% capture body %}} + + +## 角色和责任 + + + +当一个 pull 请求被合并到用于发布内容的分支(当前为“master”),该内容将发布并向全世界开放。 +为了确保发布内容的质量较高,每个 pull 请求需要 SIG Docs 的 approver 审批。 +它是这样工作的。 + + +- 当某个 pull request 拥有 `lgtm` 和 `approve` 标签, 并且没有 `hold` 标签时,这个 pull request 会自动合入。 +- Kubernetes 组织成员 和 SIG Docs 的 approvers 可以通过评论的方式阻止某个 pull request 自动合入(评论中包含 `/hold` 或 取消 `/lgtm` 的内容)。 +- 任何 Kubernetes 成员都可以通过在评论回复 `/lgtm` 来增加 `/lgtm` 标签。 +- 只有 SIG Docs 的 approver 可以在评论中回复 `/approve` 并触发合并。 + 某些 approver 还兼具其他角色,比如 [PR Wrangler](#pr-wrangler) 或 [SIG Docs chairperson](#sig-docs-chairperson)。 + + +关于 Kubernetes 组织成员和 SIG Docs approver 的区别,请参考 [Types of contributor](/docs/contribute#types-of-contributor)。 +以下部分将详细介绍这些角色及其内部的工作方式。 + +### Anyone + + +任何人可以针对 Kubernetes 的任何内容(包括文档)提交 issue。 + + +任何人想到提交 pull request,必须要签署 CLA。 否则 ubernetes 项目则不能接受你的贡献。 + +### Members + + +任何 [Kubernetes 组织成员](https://github.com/kubernetes) 都可以检视 pull request。 +SIG Docs 组成员经常需要检视来自其他 SIG 的 pull request,以确保技术上的准确性。 + + +作何 Kubernetes 组织成员都可以在评论中增加 `/hold` 标签来阻止 PR 被合入。 +任何 Kubernetes 组织成员都可以移除 `/hold` 标签来让PR 合入(必须此前已有 `/lgtm` 和 `/approve` 标签)。 + + +#### 成为一个 member + + +在你成功的提交至少5个PR后,你就可以向Kubernetes 组织提交申请 [membership](https://github.com/kubernetes/community/blob/master/community-membership.md#member)。 +按照如下流程: + + +1. 找到两个 reviewer 或 approver 为你提名。 + + 通过[#sig-docs channel on the Kubernetes Slack instance](https://kubernetes.slack.com) 或者 + [SIG Docs mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) + 来寻找为你提名的人。 + {{< note >}} + 不要单独发送邮件给某个人或在Slack中私聊。 + {{< /note >}} + +2. 在 `kubernetes/org` 仓库中提交一个 issue 发起请求。 + 按照[指导模板](https://github.com/kubernetes/community/blob/master/community-membership.md)填写请求。 + +3. 告知你的提名人,可以通过在 issue中 `@` 或者直接发送给他们issue链接, + 这样他们可以过来投票(`+1`)。 + +4. 当请求被批准后,github 管理员团队成员会告诉你批准加入并且关闭issue:"Congratulations, you are now a member!"。 + + +如果因为某些原因你的申请没有被批准,会员委员会成员会告诉你原因并指导你如何继续申请。 + +### Reviewers + + +Reviewers 是[@kubernetes/sig-docs-pr-reviews](https://github.com/orgs/kubernetes/teams/sig-docs-pr-reviews) 成员。 + + +Reviewers 负责检视文档的PR并提供反馈。 + + +每个PR都会自动分配 reviewer,任何贡献者都可以在评论中回复`/assign [@_github_handle]` +来请求某个reviewer来检视。 +如果reviewer觉得没有问题且不需要进一步更改时,reviewer 会在评论中回复 `/lgtm` 。 + + +如果自动分配的 reviewer 未能及时检视,其他的 reviewer 也会参与。 +此外,你可以指定某个 reviewer 或者等他们回复 `/lgtm`。 + + +对于不重要的更改或者非技术性的检视,SIG Docs 的 [approver](#approvers) 也可以提供 `/lgtm` 标签。 + + +如果一个reviewer在评论中回复 `/approve` 会被自动忽略。 + + +关于如何成为 SIG Docs reviewer 以及其责任、时间承诺等更多内容,请参照 +[Becoming a reviewer or approver](#becoming-an-approver-or-reviewer)。 + + +#### 成为 reviewer + + +当你满足[需求](https://github.com/kubernetes/community/blob/master/community-membership.md#reviewer)时, +你就可以成为 SIG Docs 的 reviewer。 +其他SIG的 reviewer 也需要单独向 SIG Docs 申请。 + + +通过提交一个PR并把自己加到位于 `kubernetes/website` 仓库顶层的 [top-level OWNERS file](https://github.com/kubernetes/website/blob/master/OWNERS) 文件中 +的 `reviewers` 部分,指定一个或多个当前 SIG Docs 的 approver。 + + +如果你的PR被批准,你就成为了 SIG Docs reviewer 了。 +[K8s-ci-robot](https://github.com/kubernetes/test-infra/tree/master/prow#bots-home) 会在接下来的 +PR 中请求你检视。 + + +如果构的PR被批准,你就会加入[@kubernetes/sig-docs-pr-reviews](https://github.com/orgs/kubernetes/teams/sig-docs-pr-reviews)组。 +只有`kubernetes-website-admins`组的成员才可以加入新成员。 + +### Approvers + + +approver 是GitHub [@kubernetes/sig-docs-maintainers](https://github.com/orgs/kubernetes/teams/sig-docs-maintainers) 组织成员。 +参考 [Teams and groups within SIG Docs](#teams-and-groups-within-sig-docs)。 + + +approver 有权限合入PR,这意味着他们可以发布内容到 Kubernetes 网站。 +如果一个 approver 留下 `/approve` 评论,则代表他批准了PR。 +如果非 approver 成员尝试批准,则会被自动忽略。 + + +如果某个PR已有 `/lgtm` 标签,approver 再回复一个 `/lgtm` ,则这个PR会自动合入。 +SIG Docs approver 应该只在不需要额外的技术检视的情况下才可以标记 `/lgtm`。 + + +关于如何成为 SIG Docs 的 approver 及其责任和时间承诺等信息,请参考[Becoming a reviewer or approver](#becoming-an-approver-or-reviewer)。 + + +#### 成为approver + + +当满足[要求](https://github.com/kubernetes/community/blob/master/community-membership.md#approver) +时,你可以成为 SIG Docs 的 approver。 +其他的SIG 的 approver 要想成为SIG Docs 的 approver 需要单独申请。 + + +通过提交一个PR并把自己加到位于 `kubernetes/website` 仓库顶层的 [top-level OWNERS file](https://github.com/kubernetes/website/blob/master/OWNERS) 文件中 +的 `approvers` 部分,指定一个或多个当前 SIG Docs 的 approver。 + + +一旦你的PR被批准,你就是一个 SIG Docs 的 approver 了。 + + +如果构的PR被批准,你就会加入[@kubernetes/sig-docs-maintainers](https://github.com/orgs/kubernetes/teams/sig-docs-maintainers)组。 +只有`kubernetes-website-admins`组的成员才可以加入新成员。 + +#### 成为网站管理员 + + +GitHub`kubernetes-website-admins`组织成员管理者各组的成员,并且拥有设置仓库的权限, +包括增加、删除和定位用的插件等。并不是所有的SIG Docs 的 approver 拥有此级别的权限。 + + +如果你觉得需要这个权限,可以与当前的网站管理员沟通,或者在[Kubernetes Slack](https://kubernetes.slack.com)中询问。 + + +#### PR 协调者 + + +每个 SIG Docs approver 都会被加入到 [PR Wrangler rotation scheduler](https://github.com/kubernetes/website/wiki/PR-Wranglers)。 +所有 SIG Docs approver 都会参与轮值。 +更多信息,请参考 [做一周的PR协调者](/docs/contribute/advanced#be-the-pr-wrangler-for-a-week)。 + + +#### SIG Docs 主席 + + +每个SIG,包括 SIG Docs,都会选出1位或多位成员作为主席。 +主席会成为 SIG Docs 和其他Kubernetes 组织的联络接口人。 +他们需要了解整个Kubernetes项目,并明白 SIG Docs如何运作。 +如需查询当前的主席,请查阅[Leadership](https://github.com/kubernetes/community/tree/master/sig-docs#leadership)。 + + +## SIG Docs 团队和自动化 + + +SIG文档中的自动化依赖于两种不同的自动化机制: +GitHub组和OWNERS文件。 + +### GitHub groups + + +SIG Docs 组定义了两个GitHub组: + + - [@kubernetes/sig-docs-maintainers](https://github.com/orgs/kubernetes/teams/sig-docs-maintainers) + - [@kubernetes/sig-docs-pr-reviews](https://github.com/orgs/kubernetes/teams/sig-docs-pr-reviews) + + +可以在GitHub的评论中`@name`他们来与他们沟通。 + + +这些团队与自动化工具使用的组有所重叠,但并不完全匹配。 +对于分配issue、拉请求和批准PR,自动化使用来自OWNERS文件的信息。 + + +### OWNERS 文件和扉页 + + +Kubernetes项目使用名为 prow 的自动化工具来处理 GitHub issue 和 PR。 +[Kubernetes website repository](https://github.com/kubernetes/website) 使用了两个 +[prow 插件](https://github.com/kubernetes/test-infra/blob/master/prow/plugins.yaml#L210): + +- blunderbuss +- approve + + +这两个插件使用位于 `kubernetes/website` 仓库顶层的 +[OWNERS](https://github.com/kubernetes/website/blob/master/OWNERS) 和 +[OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS_ALIASES) +来控制工作流程。 + + +OWNERS 文件包含 SIG Docs reviewer 和 approver的列表。 +OWNERS 文件也可以存在于子目录中中,可以重写 reviewer 和 approver,并且它自动继乘上级。 +关于OWNERS的更多信息,请参考[OWNERS](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md)。 + + +此外,一个单独的 Markdown 格式的文件将会列出 reviewer 和 approver(扉页),或者列出 +其GitHub 用户名 或者列出其组名。 + + +结合 OWNERS 文件及扉页可以给PR作者提供向谁请求检视的建议。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +关于贡献Kubernetes 的更多文档,请参考: + +- [Start contributing](/docs/contribute/start/) +- [Documentation style](/docs/contribute/style/) + +{{% /capture %}} + + diff --git a/content/zh/docs/contribute/start.md b/content/zh/docs/contribute/start.md new file mode 100644 index 0000000000000..a2ca496cee94b --- /dev/null +++ b/content/zh/docs/contribute/start.md @@ -0,0 +1,684 @@ +--- +title: 开始贡献 +slug: start +content_template: templates/concept +weight: 10 +card: + name: contribute + weight: 10 +--- + + + +{{% capture overview %}} + + +如果您想要为 Kubernetes 文档做贡献,本页面的内容和链接的主题能够给您帮助。您不必是一位开发者或者技术作者,也同样可以为 Kubernetes 文档及其用户体验带来巨大的影响!您只需要有一个 [Github 账号](https://github.com/join) 和一个浏览器。 + + +如果您在寻找有关如何开始向 Kubernetes 仓库贡献代码的信息,请参考 [Kubernetes 社区指南](https://github.com/kubernetes/community/blob/master/governance.md)。 + +{{% /capture %}} + + +{{% capture body %}} + + +## 关于我们文档的基础知识 + + +Kubernetes 文档是以 Markdown 形式编写的,使用 Hugo 进行部署。源码位于 Github 的 [https://github.com/kubernetes/website](https://github.com/kubernetes/website)。 +大部分文档源码位于 `/content/en/docs/`。有些参考文档是由 `update-imported-docs/` 目录内的脚本自动生产的。 + + +您可以查找 issue、编辑内容或者对其他人的提交内容进行复审,这些都可以在 Github 网站上完成。您也可以使用 Github 内置的历史功能和查询工具。 + + +并非所有的任务都可以通过 Github UI 完成,这些任务会在[中级](/docs/contribute/intermediate/)和[高级](/docs/contribute/advanced/)文档贡献指南中讨论。 + + +### 参与文档特别兴趣小组(SIG Docs) + + +Kubernetes 文档是由特别兴趣小组(SIG)维护的,该小组名为 SIG Docs。我们通过 Slack 频道、邮件列表和网络视频周会进行交流。 +欢迎新的参与者加入。更多信息,请参考[参与 SIG Docs](/docs/contribute/participating/)。 + + +### 风格指南 + + +我们维护了一个[风格指南](/docs/contribute/style/style-guide/)页面,上面有关于 SIG Docs 社区对于语法、句法、源格式和排版的约定。 +在您做首次贡献前或者在有疑问的时候请先查阅风格指南。 + + +风格的变化是由 SIG Docs 组共同决定的。如您想提交变更或增加内容,请将内容[添加到议题](https://docs.google.com/document/d/1Ds87eRiNZeXwRBEbFr6Z7ukjbTow5RQcNZLaSvWWQsE/edit#)并参与会议讨论。 +更多信息,参见[进阶贡献](/docs/contribute/advanced/)主题。 + + +### 页面模板 + + +我们使用页面模板来控制文档页面。需要确保您理解这些模版是如何工作的,请阅读[使用页面模板](/docs/contribute/style/page-templates/)。 + + +### Hugo 短代码 + + +Kubernetes 文档使用 Hugo 将 Markdown 转换成 HTML。我们使用标准的 Hugo 短代码,同时也会有部分为 Kubernetes 定制化的代码。 +有关如何使用短代码的信息,请参见[自定义 Hugo 短代码](/docs/contribute/style/hugo-shortcodes/)。 + + +### 多语言 + + +在 `/content/` 目录中有文档源码的多语言版本。每个语言拥有其自己的目录,采用 [ISO 639-1 标准](https://www.loc.gov/standards/iso639-2/php/code_list.php) 的两位编码命名。例如,英文文档源码位于 `/content/en/docs/` 目录。 + + +更多关于对多语言文档做贡献的信息,请参考中级贡献指南中的["本地化内容"](/docs/contribute/intermediate#localize-content)。 + + +如果您有兴趣开始一个新的本地化语言项目,请参考["本地化"](/docs/contribute/localization/)。 + + +## 登记文档可操作问题 + + +任何拥有 Github 账号的人都能对于 Kubernetes 文档登记一个问题(或者 bug 报告)。 +如果看到有东西坏了,即便您不知道如何修复它,请[登记一个问题](#how-to-file-an-issue)。 +除了您发现微小的错误的情况,例如发现了一个拼写错误,您想自己进行修复。在这种情况下, +您可以[修复它](#improve-existing-content),而不用先登记一个 bug。 + + +### 如何记录问题 + + +- **对于已有页面** + + + 如果您在已有的 [Kubernetes 文档](/docs/)页面,在页面底部直接点击 **创建问题** 按钮。 + 如果您当前未登录 Github,那么请登录。Github 文档表单会带着预填的信息出现。 + + + 使用 Markdown 格式,填写尽可能多的详细信息。在方括号 (`[ ]`) 中,使用 `x` 代码选择了该选项。 + 如果您提交了修复问题的方法,也填在里面。 + + +- **请求创建一个新页面** + + + 如果认为有些内容应该存在,但您不知道应该将这些内容存放在哪里,或者任何不适合放在现有页面中, + 那么也可以记录一个问题。您可以选择通过内容相近的页面创建问题,或者直接 + 在 [https://github.com/kubernetes/website/issues/new/](https://github.com/kubernetes/website/issues/new/) + 中记录问题。 + + +### 如何记录好的问题 + + +要确保我们能理解您的问题,并能付诸行动,请谨记如下指南: + + +- 使用问题模板,尽可能填写详细的信息。 +- 清楚地描述该问题对用户造成的具体影响。 +- 限制问题的范围,以提交给合理的工作组。如果问题范围很大,将其拆分成若干个小问题。 + + + 例如,“修复安全文档”就是一个不可执行的问题,但 “为'限制网络访问'主题添加详细信息”就是可执行的。 +- 如果问题与另一个问题或者拉取请求(PR)有关,您可以通过问题的完整 URL 或者 PR 的序号(以 `#` 为前缀)进行关联。例如 `源于 #987654`。 +- 保持尊重,避免发泄。例如,"这问题就是个垃圾"就是无用且不可执行的反馈。[行为准测](/community/code-of-conduct/) 也适用于 Kubernetes Github 仓库的交流。 + + +## 参与 SIG Docs 讨论 + + +SIG Docs 团队的交流采用如下机制: + + +- [加入 Kubernetes 的 Slack 工作组](http://slack.k8s.io/),然后加入 `#sig-docs` 频道,在那里我会实时讨论文档的问题。一定要做自我介绍! +- [加入 `kubernetes-sig-docs` 邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs),在这里会有广泛的讨论以及官方决策的记录。 +- 参与 [SIG Docs 视频周例会](https://github.com/kubernetes/community/tree/master/sig-docs),会通过 Slack 频道和邮件列表通知。 + 目前通过 Zoom 进行会议,所以您需要下载 [Zoom 客户端](https://zoom.us/download),或者通过手机拨入。 + + +{{< note >}} +您也可以查看 [Kubernetes 社区会议日历](https://calendar.google.com/calendar/embed?src=cgnt364vd8s86hr2phapfjc6uk%40group.calendar.google.com&ctz=America/Los_Angeles)。 +{{< /note >}} + + +## 改进现有内容 + + +要改进现有的内容,您可以在创建 _fork_ 之后起草一个 _拉取请求(PR)_ 。 +这两个术语是 [Github 专用的](https://help.github.com/categories/collaborating-with-issues-and-pull-requests/)。 +出于本主题的目的,您无需了解有关它们的所有信息,因为您可以通过浏览器做所有的事情。 +当您继续阅读[贡献者中级指南](/docs/contribute/intermediate/),您会需要更多 Git 术语的背景知识。 + + +{{< note >}} +**Kubernetes 代码开发者**: 如果您在撰写 Kubernetes 新版本的新功能文档,流程会稍有不同。 +关于流程指南和最后期限的信息,请参阅[编写功能文档](/docs/contribute/intermediate/#sig-members-documenting-new-features)。 +{{< /note >}} + + +## 签署 CLA + + +在贡献 Kubernetes 的代码或文档前,您 **必须** 阅读[贡献者指南](https://github.com/kubernetes/community/blob/master/contributors/guide/README.md), +并[签署贡献者许可协议(CLA)](https://github.com/kubernetes/community/blob/master/CLA.md)。 +别担心 -- 不需要太多时间! + + +### 找些活干 + + +如果您发现了一些想要马上修复的东西,只需要遵循如下指南。您不需要[记录一个问题](#file-actionable-issues)(尽管你当然可以这么做)。 + + +如果您想从处理现有的问题开始,前往 [https://github.com/kubernetes/website/issues](https://github.com/kubernetes/website/issues) +找一些有 `good first issue` 标签的问题(您可以使用[这个](https://github.com/kubernetes/website/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) 捷径)。 +阅读评论,确保针对此问题没有打开的 PR,并且没有人留言说他们最近正在解决这个问题(3天是个很好的规则)。留言说您会去解决这个问题。 + + +## 选择使用的 Git 分支 + + +提交 PR 最重要的方面就是选择您工作所基于的基础分支。使用如下指南来做决定: + + +- 用 `master` 来解决以及发布的内容中的问题,或者对于已经存在的内容进行改进。 +- 使用 release 分支(比如 `dev-{{< release-branch >}}` 用于 {{< release-branch >}} 发布)来撰写新的特性或者下个版本还未发布的变更说明。 +- 使用 SIG Docs 已经同意的 feature 分支来协作对现有文档进行重大改进或更改,包括内容重组或网站外观的更改。 + + +如果您还不确定应该使用哪个分支,在 Slack 上询问 `#sig-docs` 或者参与 SIG Docs 周会来确认。 + + +### 提交 PR + + +按照如下步骤进行 PR 提交以改善 Kubernetes 文档。 + + +1. 在您发现问题的页面上,点击右上角的铅笔图标。新的页面就会出现,上面会有一些帮助信息。 +2. 如果您从未创建过 Kubernetes 文档仓库的 fork,会提示您需要创建。请在您的 Github 账号 + 下创建 fork,而不是在您所在的组织下创建。fork URL 通常是这样的 `https://github.com//website`, + 出发您已经有一个同名的仓库,那样会造成冲突。 + +3. Github Markdown 编辑器会载入着文档源码一起出现。根据实际情况撰写变化内容。在编辑器下方, + 填写 **Propose file change(建议修改文件)** 表格。第一个区域需要填写提交说明消息, + 不能超过 50 个字符。第二个区域是可选的,也能够填写更多详细信息。 + + + {{< note >}} +不要把 Github 问题或者 PR 的关联信息放在您的提交说明消息中。您可以之后把这些内容添加到 PR 的描述中。 +{{< /note >}} + + + 点击 **建议修改文件(Propose file change)** 按钮。 + 变更会保存为您 fork 新分支(通常会自动命名为 `patch-1`)中的一个提交内容。 + + +4. 接下来屏幕会总结您的变更,将您的新分支(**head fork** 和 **compare** 选择框) + 与 **base fork** 和 **base** 分支(默认是 `kubernetes/website` 的 `master` 分支) + 进行比较。您可以更改选择框,但现在请不要这么做。看一下屏幕底部显示的变化内容, + 如果看起来没问题,点击 **创建 PR(Create pull request)** 按钮。 + + + {{< note >}} +如果您现在还不想创建 PR,也可以稍后再做,通过浏览 Kubernetes 网站代码仓库或者您 fork 仓库的网站主页 URL。 +Github 网站会检查到您推送了一个新分支到 fork,并提示创建 PR。 +{{< /note >}} + + +5. **Open a pull request(打开一个 PR)** 屏幕出现了。PR 的主题和提交说明的内容一致, + 如有需要您也可以修改。主体内容会自动填充您的扩展提交消息(如果存在)和一些模板文本。 + 阅读模板文本并填写要求的详细信息,然后删除额外的模板文本。 + 保留选中 **Allow edits from maintainers(允许维护者编辑)** 复选框。 + 单击 **Create pull request(创建拉取请求)** 按钮。 + + + 祝贺您!您的 PR 就出现在了[拉取请求](https://github.com/kubernetes/website/pulls) 中。 + + + 几分钟后,您可以预览 PR 所带来的变化。前往您 PR 的 **Conversation(对话)** 标签页, + 点击 `deploy/netlify` 测试的 **Details(详细信息)** 链接,它在页面底部附件。 + 默认会在同一个浏览器窗口中打开。 + + +6. 等待复审。通常,复审人员会由 `k8s-ci-robot` 建议指定。如果复审人员建议您修改,您可以 + 前往 **Files changed(改变的文件内容)** 标签页,点击任意 PR 中改变的文件页面上的铅笔图标。 + 保存更改的文件时,将在 PR 监视的分支中创建新的提交。 + + +7. 如果修改被接受,复审人员会合并您的 PR,修改就会在几分钟后在 Kubernetes 网站上生效。 + + +这是提交 PR 的唯一方式。如果您已经是一名 Git 和 Github 的高级用户,您也可以使用本地 GUI 或者 +Git 命令行。关于使用 Git 客户端的基础会在[中级](/docs/contribute/intermediate/) 贡献者指南中讨论。 + + +## 复审文档 PR + + +就算不是批注者或者复审者,也同样可以复审 PR。复审人员并不是"固定"的,意味着您单独的评审并不会让 PR 合并。 +然而,这依然对我们是很有帮助的。即使您没有留下任何评审意见,您可以了解 PR 的规范和礼仪,并习惯工作流程。 + + +1. 前往 [https://github.com/kubernetes/website/pulls](https://github.com/kubernetes/website/pulls)。 + 请会看到一个列表,里面包含了所有对于 Kubernetes 网站和文档提的 PR。 + + +2. 默认情况下,使用的筛选器是 `open`,所以您不会看见已经关闭或合并的 PR。 + 最好使用 `cncf-cla: yes` 筛选器,并且对于第一次复审来说,最好加上 `size/S` + 或者 `size/XS`。`size` 标签会根据 PR 修改的代码行数自动生成。 + 您可以通过页面顶端的选择框应用筛选器,或者使用 + [这个捷径](https://github.com/kubernetes/website/pulls?q=is%3Aopen+is%3Apr+label%3A%22cncf-cla%3A+yes%22+label%3Asize%2FS) + 来查找所有小型 PR。所有筛选条件都是 `与` 的,所以您不能在一次查询中同时查找 `size/XS` 和 `size/S` 的结果。 + + +3. 前往 **Files changed(文件修改)** 标签页。查看 PR 中的变化部分,如果适用,也看一下关联的问题。 + 如果您发现问题或者可以改进的空间,将鼠标悬浮在那一行并点击前面出现的 `+` 加号。 + + + 你可以留下评论,选择 **Add single comment(仅添加评论)** 或者也可以 **Start a review(开始复审)**。 + 典型来说,开始复审更好,因为这样您就可以在多行下留下评论,并且只有在完成复审后统一提交并通知 PR 的作者, + 而不是每一条评论都发送通知。 + + +4. 完成后,点击页面顶端但 **Review changes(复审修改)** 按钮。您可以总结复审,并且可以选择 + comment(评论),approve(批准),或者 request changes(请求变更)。 + 新的贡献者应该选择 **Comment(评论)**。 + + +感谢您对于 PR 的复审工作!当您对于项目还是新人时,最好在拉取请求评论中征求反馈意见。 +Slack 的 `#sig-docs` 频道就是一个征求意见好去处。 + + +## 撰写一篇博客文章 + + +任何人都可以撰写博客并提交复审。博客文章不应具有商业性质,而应包含广泛适用于 Kubernetes 社区的内容。 + + +要提交博客文章,您可以选择使用 [Kubernetes 博客提交表单](https://docs.google.com/forms/d/e/1FAIpQLSch_phFYMTYlrTDuYziURP6nLMijoXx_f7sLABEU5gWBtxJHQ/viewform) +或者按如下步骤进行: + + +1. [签署 CLA](#sign-the-cla),如果您还未签署的话。 +2. 查看现有博客文章的 Markdown 格式,位于[网站代码仓库](https://github.com/kubernetes/website/tree/master/content/en/blog/_posts)。 +3. 在您选择的文本编辑器中写下您的博客文章。 +4. 在步骤 2 的相同链接中,点击 **Create new file(创建新文件)** 按钮。 + 将您的内容粘贴到编辑器中。将文件命名为与博客文章的标题的名称, + 但不要将日期放在文件名中。博客复审人员将与您一起确定最终文件名和博客发布日期。 +5. 保存文件时,Github 将引导您完成 PR 过程。 +6. 博客复审人员会对您提交对内容进行复审,并与您一起完成反馈意见和最终的详细信息。 + 博客文章获得批准后,博客将会安排时间进行发布。 + + +## 提交一个案例研究 + + +案例研究强调组织如何使用 Kubernetes 解决实际问题。它们是由 Kubernetes 市场团队共同撰写的,由 CNCF 进行处理。 + + +看一下[现有案例研究](https://github.com/kubernetes/website/tree/master/content/en/case-studies)的源码。 +使用 [Kubernetes 案例研究提交表](https://www.cncf.io/people/end-user-community/)提交您的提案。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +当您对本主题中讨论的所有任务感到满意,并且您希望以更深入的方式与 Kubernetes 文档团队合作, +请阅读[中级贡献者指南](/docs/contribute/intermediate/)。 + +{{% /capture %}} diff --git a/content/zh/docs/contribute/style/_index.md b/content/zh/docs/contribute/style/_index.md new file mode 100644 index 0000000000000..aacaf26575a73 --- /dev/null +++ b/content/zh/docs/contribute/style/_index.md @@ -0,0 +1,21 @@ +--- +title: 文档风格概述 +main_menu: true +weight: 80 +--- + + + + + +本节的主题是提供有关编写风格、内容格式和组织以及使用 Hugo 定制生成 Kubernetes 文档的指导。 diff --git a/content/zh/docs/contribute/style/content-organization.md b/content/zh/docs/contribute/style/content-organization.md new file mode 100644 index 0000000000000..3ce7964655101 --- /dev/null +++ b/content/zh/docs/contribute/style/content-organization.md @@ -0,0 +1,270 @@ +--- +title: 内容组织 +content_template: templates/concept +weight: 40 +--- + + + + +{{% capture overview %}} + + + +本网站使用了 Hugo。在 Hugo 中,[内容组织](https://gohugo.io/content-management/organization/) 是一个核心概念。 + +{{% /capture %}} + +{{% capture body %}} + +{{% note %}} + + +**Hugo 提示:** 用 `hugo server --navigateToChanged` 命令启动 Hugo 以进行内容编辑会话。 +{{% /note %}} + + + +## 页面列表 + + + +### 页面顺序 + + + +文档侧方菜单、文档页面浏览器等以 Hugo 的默认排序顺序列出,它按照权重(从1开始)、日期(最新的排第一个)排序,最后按链接标题排序。 + + + +如果你想提升一个页面或一个章节,请在页面头部设置一个较高的权重: + +```yaml +title: My Page +weight: 10 +``` + + +{{% note %}} + + +对于页面的权重,不建议使用连续的数值,比如1、2、3...,而是采用间隔的数值,比如10、20、30...,这样你可以将后续的页面插入到想要的位置。 +{{% /note %}} + + + + +### 文档主菜单 + + + +`Documentation` 主菜单是从 `docs/` 下面的章节构建的,它在 `_index.md` 章节内容文件的头部设置了 `main_menu` 标志: + + +```yaml +main_menu: true +``` + + + + +注意,链接标题是从页面的 `linkTitle` 中提取的,因此如果希望它与标题不同,请在内容文件中更改它: + + +```yaml +main_menu: true +title: Page Title +linkTitle: Title used in links +``` + + +{{% note %}} + + +以上每种语言都需要完成。如果在菜单中没有看到你的章节,这可能是因为它没有被 Hugo 标识为一个章节。请在章节对应的目录下创建 `_index.md` 内容文件。 +{{% /note %}} + + + +### 文档侧方菜单 + + + +文档侧方菜单是从 `docs/` 下面的 _current 章节的 tree_ 开始构建的。 + + + +它将显示所有的章节和它们的页面。 + + + +如果你不想列出某个章节或页面,请在页面头部将 `toc_hide` 标志设置为 `true`。 + +```yaml +toc_hide: true +``` + + + +当导航到具有内容的章节时,将显示出指定的章节或页面(例如 `_index.md`)。否则,将显示该章节里的第一个页面。 + + + +### 文档浏览器 + + + +文档主页上的页面浏览器是用 `docs section` 下一层的所有章节和页面构建的。 + + + +如果你不想列出某个章节或页面,请在页面头部将 `toc_hide` 标志设置为 `true`。 + +```yaml +toc_hide: true +``` + + + +### 主菜单 + + + +右上菜单中的网站链接(也在页脚中)是通过页面查找构建的。这是为了确保页面实际存在。因此,如果 `case-studies` 章节在网站中不存在(按语言),则它将链接不到。 + + + + +## 页面包 + + + +除了独立的内容页面(Markdown文件),Hugo 还支持 [页面包](https://gohugo.io/content-management/page-bundles/)。 + + + +一个例子是 [定制 Hugo 短代码](/docs/contribute/style/hugo-shortcodes/)。它被认为是 `leaf bundle`。目录下的所有内容,包括 `index.md`,都是包的一部分。这还包括页面相关的链接、可被处理的图像等: + +```bash +en/docs/home/contribute/includes +├── example1.md +├── example2.md +├── index.md +└── podtemplate.json +``` + + + +另一个广泛使用的例子是 `includes` 包。它在页面头部设置 `headless: true`,这意味着它没有得到自己的 URL。它只用于其他页面。 + +```bash +en/includes +├── default-storage-class-prereqs.md +├── federated-task-tutorial-prereqs.md +├── federation-content-moved.md +├── index.md +├── partner-script.js +├── partner-style.css +├── task-tutorial-prereqs.md +├── user-guide-content-moved.md +└── user-guide-migration-notice.md +``` + + + +包中文件的一些重要说明: + + + +* 对于已翻译的包,任何丢失的非内容文件将从上面的语言继承。这避免了重复。 +* 包中的所有文件都是 Hugo 所指的 `Resources`,你可以为每种语言提供元数据,例如参数和标题,即使它不支持头部设置(YAML 文件等)。参见[页面资源元数据](https://gohugo.io/content-management/page-resources/#page-resources-metadata)。 +* 从 `Resource` 的 `.RelPermalink` 中获得的值是页面相关的。参见 [Permalinks](https://gohugo.io/content-management/urls/#permalinks)。 + + + + +## 样式 + + + +本网站的样式表的 `SASS` 源存储在 `src/sass` 下面,可以用 `make sass` 构建(Hugo很快就会得到 `SASS` 的支持,参见https://github.com/gohugoio/hugo/issues/4243)。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +* [定制 Hugo 短代码](/docs/contribute/style/hugo-shortcodes/) +* [样式指南](/docs/contribute/style/style-guide) + +{{% /capture %}} diff --git a/content/zh/docs/contribute/style/hugo-shortcodes/example1.md b/content/zh/docs/contribute/style/hugo-shortcodes/example1.md new file mode 100644 index 0000000000000..0656ce4883908 --- /dev/null +++ b/content/zh/docs/contribute/style/hugo-shortcodes/example1.md @@ -0,0 +1,23 @@ +--- +title: 例子 #1 +--- + + + + + +这是一个内容文件**示例**,位于一个**includes**叶子包中。 + +{{< note >}} + + +包含的内容文件也可以包含短代码。 +{{< /note >}} \ No newline at end of file diff --git a/content/zh/docs/contribute/style/hugo-shortcodes/example2.md b/content/zh/docs/contribute/style/hugo-shortcodes/example2.md new file mode 100644 index 0000000000000..356983f3c0029 --- /dev/null +++ b/content/zh/docs/contribute/style/hugo-shortcodes/example2.md @@ -0,0 +1,17 @@ +--- +title: 例子 #1 +--- + + + + + +这是另一个内容文件**示例**,位于一个**includes**叶子包中。 + + diff --git a/content/zh/docs/contribute/style/hugo-shortcodes/index.md b/content/zh/docs/contribute/style/hugo-shortcodes/index.md new file mode 100644 index 0000000000000..b9523c72170a6 --- /dev/null +++ b/content/zh/docs/contribute/style/hugo-shortcodes/index.md @@ -0,0 +1,272 @@ +--- +approvers: +- chenopis +title: 定制 Hugo 短代码 +content_template: templates/concept +--- + + + +{{% capture overview %}} + +本页面将介绍定制 Hugo 短代码,可以用于 Kubernetes markdown 文档书写。 + + +更多关于短代码参见 [Hugo 文档](https://gohugo.io/content-management/shortcodes)。 +{{% /capture %}} + +{{% capture body %}} + +## 功能状态 + + +本站上面的 markdown 页面,你可以加入短代码来展示已经文档介绍的功能的版本和状态(state)。 + + +### 功能状态演示 + + +下面是一个功能状态代码段的演示,表明这个功能已经在 Kubernetes v1.10时就已经稳定了。 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state for_k8s_version="v1.10" state="stable" >}} + + +`state`的可选值如下: + +* alpha +* beta +* deprecated +* stable + + +### 功能状态代码 + + +下面是为每个现有的功能状态的模板代码。 + + + +显示的 Kubernetes 默认为该页或站点版本。 +这个可以通过修改 for_k8s_version 短代码参数来调整。 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state for_k8s_version="v1.10" state="stable" >}} + + +#### Alpha 功能 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state state="alpha" >}} + + + +#### Beta 功能 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state state="beta" >}} + + +#### 稳定功能 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state state="stable" >}} + + +#### 废弃功能 + +``` +{{}} +``` + + +会转换为: + +{{< feature-state state="deprecated" >}} + + +## 词汇 + + + +你可以通过加入术语词汇的短代码,来自动更新和替换相应链接中的内容([我们的词汇库](/docs/reference/glossary/)) +这样,在浏览在线文档,鼠标移到术语上时,术语解释就会显示在提示框中。 + + + +词汇术语的原始数据保存在 [https://github.com/kubernetes/website/tree/master/content/en/docs/reference/glossary](https://github.com/kubernetes/website/tree/master/content/en/docs/reference/glossary),每个内容文件对应相应的术语解释。 + + +### 词汇演示 + + + +例如,下面的代码在 markdown 中将会转换为 `{{< glossary_tooltip text="cluster" term_id="cluster" >}}`,然后在提示框中显示。 + +````liquid +{{}} +```` + + +## 标签页 + + +在本站的 markdown 页面(`.md` 文件)中,你可以加入一个标签页集来显示不同形式的解决方案。 + + +标签页的短代码包含以下参数: + + + +* `name`: 标签页上的名字。 +* `codelang`: 如果要在`tab`短代码中加入内部内容,需要告知 Hugo 使用的是什么代码语言,方便代码高亮。 +* `include`: 标签页中所要包含的文件。如果标签页是在 Hugo 的页面包([leaf bundle](https://gohugo.io/content-management/page-bundles/#leaf-bundles))中,文件(可以是 Hugo 所支持的 MIME 类型文件)将会在包中查找。如果不是,所要包含的内容页面将会在当前路径的相关路径下查找。注意,在`include`属性部分,不能加入短代码内部内容,必须要使用自结束(self-closing)的语法。 +非内容文件将会被代码高亮。如果没有在`codelang`进行声明的话,所用的代码语言将会来自文件名。 + + + +* 如果内部内容是 markdown, 你必须要使用 `%` 分隔符来包装标签页,例如,`{{%/* tab name="Tab 1" %}}This is **markdown**{{% /tab */%}}` +* 可以在标签页集中混合使用上面的各种变形。 + + +下面是演示标签页短代码。 + +{{< note >}} +The tab **name** in a `tabs` definition must be unique within a content page. +一个内容页面下的,标签页定义中的标签页 **名** 必须是唯一的。 +{{< /note >}} + + +### 标签页演示:代码高亮 + +```go-text-template +{{}} +{{{< tab name="Tab 1" codelang="bash" >}} +echo "This is tab 1." +{{< /tab >}} +{{< tab name="Tab 2" codelang="go" >}} +println "This is tab 2." +{{< /tab >}}} +{{< /tabs */>}} +``` + + +会转换为: + +{{< tabs name="tab_with_code" >}} +{{< tab name="Tab 1" codelang="bash" >}} +echo "This is tab 1." +{{< /tab >}} +{{< tab name="Tab 2" codelang="go" >}} +println "This is tab 2." +{{< /tab >}} +{{< /tabs >}} + +### Tabs demo: Inline Markdown and HTML + +```go-html-template +{{}} +{{% tab name="Markdown" %}} +This is **some markdown.** +{{< note >}}**Note:** It can even contain shortcodes.{{< /note >}} +{{% /tab %}} +{{< tab name="HTML" >}} +
+

Plain HTML

+

This is some plain HTML.

+
+{{< /tab >}} +{{< /tabs */>}} +``` + + +会转换为: + +{{< tabs name="tab_with_md" >}} +{{% tab name="Markdown" %}} +This is **some markdown.** +{{< note >}}**Note:** It can even contain shortcodes.{{< /note >}} +{{% /tab %}} +{{< tab name="HTML" >}} +
+

Plain HTML

+

This is some plain HTML.

+
+{{< /tab >}} +{{< /tabs >}} + + +### 标签页演示:文件嵌套 + +```go-text-template +{{}} +{{< tab name="Content File #1" include="example1" />}} +{{< tab name="Content File #2" include="example2" />}} +{{< tab name="JSON File" include="podtemplate" />}} +{{< /tabs */>}} +``` + + +会转换为: + +{{< tabs name="tab_with_file_include" >}} +{{< tab name="Content File #1" include="example1" />}} +{{< tab name="Content File #2" include="example2" />}} +{{< tab name="JSON File" include="podtemplate" />}} +{{< /tabs >}} + + +{{% /capture %}} + +{{% capture whatsnext %}} + + +* 了解 [Hugo](https://gohugo.io/)。 +* 了解 [撰写新的话题](/docs/home/contribute/write-new-topic/)。 +* 了解 [使用页面模板](/docs/home/contribute/page-templates/)。 +* 了解 [暂存修改](/docs/home/contribute/stage-documentation-changes/)。 +* 了解 [创建 pull request](/docs/home/contribute/create-pull-request/)。 +{{% /capture %}} diff --git a/content/zh/docs/contribute/style/page-templates.md b/content/zh/docs/contribute/style/page-templates.md new file mode 100644 index 0000000000000..f1afdff4279ce --- /dev/null +++ b/content/zh/docs/contribute/style/page-templates.md @@ -0,0 +1,352 @@ +--- +title: 使用页面模板 +content_template: templates/concept +weight: 30 +--- + + + +{{% capture overview %}} + + + +当贡献新主题时,选择下列模板中的一种。 +这使指定页面的用户体验标准化。 + + + +页面模板在 [`kubernetes/website`](https://github.com/kubernetes/website) 仓库的 [`layouts/partials/templates`](https://git.k8s.io/website/layouts/partials/templates) 目录中。 + +{{< note >}} + + +每个新主题都需要使用模板。如果你不确定新主题要使用哪个模板,请从[概念模板](#concept-template)开始。 +{{< /note >}} + + +{{% /capture %}} + + +{{% capture body %}} + + + +## 概念模板 + + + +每个概念页面负责解释 Kubernetes 的某方面。例如,概念页面可以描述 Kubernetes Deployment 对象,并解释当部署、扩展和更新时,它作为应用程序所扮演的角色。一般来说,概念页面不包括步骤序列,而是提供任务或教程的链接。 + + + + +要编写新的概念页面,请在 `/content/en/docs/concepts` 目录的子目录中创建一个 Markdown 文件,其特点如下: + + + +- 在页面的 YAML 头部,设置 `content_template: templates/concept`。 +- 在页面的 body 中,设置所需的 `capture` 变量和所有想要包含的变量: + + | 变量 | 必需? | + |---------------|-----------| + | overview | 是 | + | body | 是 | + | whatsnext | 否 | + + + + 页面的 body 看起来像这样(移除所有不想要的可选 `capture` 变量): + + ``` + {{%/* capture overview */%}} + + {{%/* /capture */%}} + + {{%/* capture body */%}} + + {{%/* /capture */%}} + + {{%/* capture whatsnext */%}} + + {{%/* /capture */%}} + ``` + + + +- 在每个章节中写下你的内容。请遵从以下规则: + - 使用不低于 H2 级别的标题(避免使用 H1 的标题,但 H3、H4 的标题是可以的)(以两个 `#` 字符开头)。这些章节本身是由模板自动命名的。 + - 在 `overview` 节,用一个段落的篇幅来为当前话题设定语境。 + - 在 `body` 节,使用自由形式的 Markdown 文件来解释概念。 + - 在 `whatsnext` 节,列出读者接下来可能感兴趣的最多 5 个主题。 + + + +使用概念模板的已发布主题的一个示例是[注解](/docs/concepts/overview/working-with-objects/annotations/)。你当前正在阅读的页面也使用概念模板。 + + + +## 任务模板 + + + +任务页面展示了如何完成单个任务,通常是通过给出一个简短的步骤序列。任务页面中解释性质的文字极少,但是通常会给出提供相关背景和知识的概念主题的链接。 + + + +要编写新的任务页面,请在 `/content/en/docs/tasks` 目录的子目录中创建一个 Markdown 文件,其特点如下: + + + +- 在页面的 YAML 头部,设置 `content_template: templates/task`。 +- 在页面的 body 中,设置所需的 `capture` 变量和所有想要包含的变量: + + | 变量 | 必需? | + |---------------|-----------| + | overview | 是 | + | prerequisites | 是 | + | steps | 否 | + | discussion | 否 | + | whatsnext | 否 | + + + + 页面的 body 看起来像这样(移除所有不想要的可选 `capture` 变量): + + ``` + {{%/* capture overview */%}} + + {{%/* /capture */%}} + + {{%/* capture prerequisites */%}} + + {{}} {{}} + + {{%/* /capture */%}} + + {{%/* capture steps */%}} + + {{%/* /capture */%}} + + {{%/* capture discussion */%}} + + {{%/* /capture */%}} + + {{%/* capture whatsnext */%}} + + {{%/* /capture */%}} + ``` + + + +- 在每个章节中写下你的内容。请遵从以下规则: + - 使用不低于 H2 级别的标题(避免使用 H1 的标题,但 H3、H4 的标题是可以的)(以两个 `#` 字符开头)。这些章节本身是由模板自动命名的。 + - 在 `overview` 节,用一个段落的篇幅来为当前话题设定语境。 + - 在 `prerequisites 节`,如果有可能,请使用列表。在 `include` 下开始添加额外的先决条件。默认的先决条件包括运行中的 Kubernetes 集群。 + - 在 `steps` 节,使用编号列表。 + - 在讨论部分,使用通常的内容来扩展 `steps` 中包含的信息。 + - 在 `whatsnext` 节,列出读者接下来可能感兴趣的最多 5 个主题。 + + + +使用任务模板的已发布主题的一个示例是[使用 HTTP 代理访问 Kubernetes API](/docs/tasks/access-kubernetes-api/http-proxy-access-api)。 + + + +## 教程模板 + + + +教程页面展示了如何完成比单个任务更大的目标。通常教程页有几个章节,每个章节都有步骤说明。例如,教程可以提供说明 Kubernetes 的特定特性的代码示例的演练。教程可以包括表层解释,但是应该链接到相关的概念主题以进行深入解释。 + + + +要编写新的教程页面,请在 `/content/en/docs/tutorials` 目录的子目录中创建一个 Markdown 文件,其特点如下: + + + +- 在页面的 YAML 头部,设置 `content_template: templates/tutorial`。 +- 在页面的 body 中,设置所需的 `capture` 变量和所有想要包含的变量: + + | 变量 | 必需? | + |---------------|-----------| + | overview | 是 | + | prerequisites | 是 | + | objectives | 是 | + | lessoncontent | 是 | + | cleanup | 否 | + | whatsnext | 否 | + + + + 页面的 body 看起来像这样(移除所有不想要的可选 `capture` 变量): + + ``` + {{%/* capture overview */%}} + + {{%/* /capture */%}} + + {{%/* capture prerequisites */%}} + + {{}} {{}} + + {{%/* /capture */%}} + + {{%/* capture objectives */%}} + + {{%/* /capture */%}} + + {{%/* capture lessoncontent */%}} + + {{%/* /capture */%}} + + {{%/* capture cleanup */%}} + + {{%/* /capture */%}} + + {{%/* capture whatsnext */%}} + + {{%/* /capture */%}} + ``` + + + +- 在每个章节中写下你的内容。请遵从以下规则: + - 使用不低于 H2 级别的标题(避免使用 H1 的标题,但 H3、H4 的标题是可以的)(以两个 `#` 字符开头)。这些章节本身是由模板自动命名的。 + - 在 `overview` 节,用一个段落的篇幅来为当前话题设定语境。 + - 在 `prerequisites` 节,如果有可能,请使用列表。在默认情况下添加额外的先决条件。 + - 在 `objectives` 节,使用列表。 + - 在 `lessoncontent` 节,适当地使用编号列表和叙述内容的组合。 + - 在 `cleanup` 节,使用编号列表描述完成任务后清理集群状态的步骤。 + - 在 `whatsnext` 节,列出读者接下来可能感兴趣的最多 5 个主题。 + + + +使用教程模板的已发布主题的一个示例是[使用部署运行无状态应用程序](/docs/tutorials/stateless-application/run-stateless-application-deployment/)。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + + +- 学习[样式指南](/docs/contribute/style/style-guide/) +- 学习[内容组织](/docs/contribute/style/content-organization/) + +{{% /capture %}} diff --git a/content/zh/docs/contribute/style/write-new-topic.md b/content/zh/docs/contribute/style/write-new-topic.md new file mode 100644 index 0000000000000..82378bf1be8b8 --- /dev/null +++ b/content/zh/docs/contribute/style/write-new-topic.md @@ -0,0 +1,346 @@ +--- +title: 撰写新主题 +content_template: templates/task +weight: 20 +--- + + + +{{% capture overview %}} + + +本页面展示如何为 Kubernetes 文档库创建新主题。 +{{% /capture %}} + +{{% capture prerequisites %}} + + +创建 Kubernetes 文档仓库的一个分支,如[开始贡献](/docs/contribute/start/)中所述。 +{{% /capture %}} + +{{% capture steps %}} + + + +## 选择页面类型 + + + +当你准备写一个新的主题时,考虑一下最适合你的内容的页面类型: + + + + + + + + + + + + + + + + + + + + +
概念每个概念页面负责解释 Kubernetes 的某方面。例如,概念页面可以描述 Kubernetes Deployment 对象,并解释当部署、扩展和更新时,它作为应用程序所扮演的角色。一般来说,概念页面不包括步骤序列,而是提供任务或教程的链接。一个概念主题的示例,请参见 节点.
任务任务页面展示了如何完成单个任务。这样做的目的是给读者一系列步骤,让他们在阅读时能够真正做到这一点。任务页面可长可短,前提是它始终聚焦在一个区域。在任务页面中,可以将简短的解释与要执行的步骤混合在一起,但如果需要提供冗长的解释,则应在概念主题中进行。相关联的任务和概念主题可以相互链接。一个简短的任务页面的实例,请参见 配置一个使用卷进行存储的 Pod. 一个较长的任务页面的实例,请参见 配置活动性和就绪性探测器
教程教程页面展示了如何实现将几个 Kubernetes 特性联系在一起的目标。教程可能提供一些步骤序列,读者可以在阅读页面时实际执行这些步骤。或者它可以提供相关代码片段的解释。例如,教程可以提供代码示例的演练。教程可以包括对 Kubernetes 几个关联特性的简要解释,但应该链接到相关概念主题,以便深入解释各个特性。
+ + + +为每个新页面使用模板。每种页面类型都有一个[模板](/docs/contribute/style/page-templates/)可以在编写主题时使用。使用模板有助于确保给定类型主题之间的一致性。 + + + +## 选择标题和文件名 + + + +选择一个标题,标题中包含了要通过搜索引擎要查找的关键字。创建一个文件名,使用标题中由连字符分隔的单词。例如,标题为[使用 HTTP 代理访问 Kubernetes API](/docs/tasks/access-kubernetes-api/http-proxy-access-api/) 的主题的文件名为 `http-proxy-access-api.md`。你不需要在文件名中加上 "kubernetes",因为 "kubernetes" 已经在主题的 URL 中了,例如: + + /docs/tasks/access-kubernetes-api/http-proxy-access-api/ + + + +## 在页面头部添加主题标题 + + + +在你的主题中,在[页面头部](https://jekyllrb.com/docs/frontmatter/)设置一个 `title` 字段。页面头部是位于页面顶部三条虚线之间的 YAML 块。下面是一个例子: + + + + --- + title: 使用 HTTP 代理访问 Kubernetes API + --- + + + +## 选择目录 + + + +根据页面类型,将新文件放入其中一个子目录中: + +* /content/en/docs/tasks/ +* /content/en/docs/tutorials/ +* /content/en/docs/concepts/ + + + +你可以将文件放在现有的子目录中,也可以创建一个新的子目录。 + + + +## 将主题放在目录中 + + + +目录是使用文档源的目录结构动态构建的。`/content/en/docs/` 下的顶层目录创建顶层导航,它和子目录在目录中都有条目。 + + + +每个子目录都有一个 `_index.md` 文件,它表示指定子目录内容的主页面。`_index.md` 文件不需要模板。它可以包含有关子目录中主题的概述内容。 + + + +默认情况下,目录中的其他文件按字母顺序排序。这几乎不是最好的顺序。要控制子目录中主题的相对排序,请将页面头部的键 `weight:` 设置为整数。通常我们使用10的倍数,添加后续主题时权重值递增。例如,权重为 `10` 的主题将位于权重为 `20` 的主题之前。 + + + +## 在主题中嵌入代码 + + + +如果你想在主题中包含一些代码,可以直接使用标记代码块语法将代码嵌入到文件中。建议用于以下情况(并非详尽列表): + + + +- 代码显示来自命令的输出,例如 `kubectl get deploy mydeployment -o json | jq '.status'`。 +- 代码不够通用,用户无法验证。例如,你可以嵌入 YAML 文件来创建一个依赖于特定 [Flexvolume](/docs/concepts/storage/volumes#flexvolume)实现的 Pod。 +- 该代码是一个不完整的示例,因为它的目的是高亮显示大文件的部分内容。例如,在描述自定义 [PodSecurityPolicy](/docs/tasks/administer-cluster/sysctl-cluster/#podsecuritypolicy)的方法时,出于某些原因,你可以直接在主题文件中提供一个简短的片段。 +- 由于其他原因,该代码不适合用户验证。例如,当使用 `kubectl edit` 命令描述如何将新属性添加到资源时,你可以提供一个仅包含要添加的属性的简短示例。 + + + +## 引用来自其他文件的代码 + + + +在主题中引用代码的另一种方法是创建一个新的、完整的示例文件(或示例文件组),然后从主题中引用这些示例。当示例是通用的和可重用的,并且你希望读者自己验证时,使用此方法引用示例 YAML 文件。 + + + +添加新的独立示例文件(如 YAML 文件)时,将代码放在 `/examples/` 的某个子目录中,其中 `` 是该主题的语言。在主题文件中使用 `codenew` 短代码: + +
{{< codenew file="<RELPATH>/my-example-yaml>" >}}
+ + + +`` 是要引用的文件的路径,相对于 `examples` 目录。以下 Hugo 短代码引用了位于 `/content/en/examples/pods/storage/gce-volume.yaml` 的 YAML 文件。 + +```none +{{}} +``` + +{{< note >}} + + +要展示上述示例中的原始 Hugo 短代码并避免 Hugo 对其进行解释,请直接在 `<` 字符之后和 `>` 字符之前使用 C 样式注释。请查看此页面的代码。 +{{< /note >}} + + + +## 显示如何从配置文件创建 API 对象 + + + +如果需要演示如何基于配置文件创建 API 对象,请将配置文件放在 `/examples` 下的某个子目录中。 + + + +在主题中展示以下命令: + +``` +kubectl create -f https://k8s.io/examples/pods/storage/gce-volume.yaml +``` + +{{< note >}} + + +将新的 YAML 文件添加到 `/examples` 目录时,请确保该文件也在 `/examples_test.go` 文件中被引用。当提交拉取请求时,网站的 Travis CI 会自动运行此测试用例,以确保所有示例都通过测试。 +{{< /note >}} + + + +有关使用此技术的主题的示例,请参见[运行单实例有状态的应用](/docs/tutorials/stateful-application/run-stateful-application/)。 + + + +## 向主题添加镜像 + + + +将镜像文件放入 `/images` 目录。首选的镜像格式是 SVG。 + +{{% /capture %}} + +{{% capture whatsnext %}} + + +* 学习[使用页面模板](/docs/home/contribute/page-templates/)。 +* 学习[展示你的修改](/docs/home/contribute/stage-documentation-changes/)。 +* 学习[创建一个拉取请求](/docs/home/contribute/create-pull-request/)。 +{{% /capture %}} diff --git a/content/zh/docs/doc-contributor-tools/README.md b/content/zh/docs/doc-contributor-tools/README.md new file mode 100644 index 0000000000000..fe0e37a2c7e18 --- /dev/null +++ b/content/zh/docs/doc-contributor-tools/README.md @@ -0,0 +1,7 @@ +Kubernetes 文档贡献者的工具。 查看子目录内的 `README.md` 文件以获取更多信息。 + + + diff --git a/content/zh/docs/doc-contributor-tools/snippets/README.md b/content/zh/docs/doc-contributor-tools/snippets/README.md new file mode 100644 index 0000000000000..4058cbd4b62f3 --- /dev/null +++ b/content/zh/docs/doc-contributor-tools/snippets/README.md @@ -0,0 +1,84 @@ + +# Atom 的代码段 + + + +代码段就是可以插入到编辑器中的一段文本,可以节省键入时间,减少语法错误。 +`atom-snippets.cson` 文件中所提供的代码段只用于在 Atom 中的 Markdown 文件。 + + +## 安装 + + + +将 `atom-snippets.cson` 文件中的内容复制到现有的`~/.atom/snippets.cson` 之中。 +**不要替换现有的文件。** + + +不需要重启 Atom。 + + +## 使用 + + + +浏览一遍 `atom-snippets.cson` 文件,记下代码段的标题和 `prefix`。 + + + +你可以使用以下任意一种方式来触发相应的代码段: +- 键入代码段的`prefix`,按下 `` 键 +- 在 **Packages / Snippets / Available** 中搜索代码段的标题 + + + +例如,打开一个 Markdown 文件,键入 `anote`,按下 ``。 +就会插入一段带有正确的 Hugo 短代码的空注释。 + + + +代码段可以插入一行或多行文本。一些代码行都设有预留值。想要切换到下一个预留值,再按一次`` 键即可。 + + + +一些代码段只会插入部分格式的 Markdown 或 Hugo 语法。 +例如,`coverview` 只会插入一个概念概览的开始标签,而`cclose`则会插入一个结束标签。 +这是因为每类 capture 都需要一个 capture-close 标签。 + + +## 使用代码段创建新的话题 + + +从空白文件中,创建一个新的概念,任务或者教程,使用以下的代码段: + +- `newconcept` +- `newtask` +- `newtutorial` + + +预设文本包含其中。 + + +## 提交新的代码段 + + + +1. 本地开发代码段,验证是否有效。 +2. 将代码单复制到 Github 的 `atom-snippets.cson` 文件中。 +提交 pull request,邀请 Kubernetes Slack `#sig-docs` 中的另外一名 Atom 用户进行审查。 diff --git a/content/zh/docs/getting-started-guides/_index.md b/content/zh/docs/getting-started-guides/_index.md new file mode 100755 index 0000000000000..e2e9a092eaab9 --- /dev/null +++ b/content/zh/docs/getting-started-guides/_index.md @@ -0,0 +1,11 @@ +--- +title: "独立解决方案" +weight: 50 +--- + + diff --git a/content/zh/docs/getting-started-guides/alternatives.md b/content/zh/docs/getting-started-guides/alternatives.md new file mode 100644 index 0000000000000..36b4755d67f9e --- /dev/null +++ b/content/zh/docs/getting-started-guides/alternatives.md @@ -0,0 +1,22 @@ +--- +title: 弃用的替代品 +--- + + +# *停止。这些指南已被[Minikube](../minikube/)所取代,这里列出它们只是为了保持完整性。* + + +* [使用 Vagrant](https://git.k8s.io/community/contributors/devel/vagrant.md) +* *更高级的:* [直接使用 Kubernetes 原始二进制程序(仅限 Linux 系统)](https://git.k8s.io/community/contributors/devel/running-locally.md) + \ No newline at end of file diff --git a/content/zh/docs/getting-started-guides/fedora/fedora_manual_config.md b/content/zh/docs/getting-started-guides/fedora/fedora_manual_config.md new file mode 100644 index 0000000000000..596c87f6838ae --- /dev/null +++ b/content/zh/docs/getting-started-guides/fedora/fedora_manual_config.md @@ -0,0 +1,345 @@ +--- +reviewers: +- aveshagarwal +- eparis +- thockin +title: Fedora (单节点) +--- + + + +{{< toc >}} + + + +## 前提条件 + + + +1. 您需要两台或更多机器安装 Fedora。这些机器可以是裸机,也可以是虚拟机。 + +## 说明 + +这是 Fedora 的入门指南。配置手工打造,因而需要了解所有底层软件包/服务/端口等等。 + +本指南只能使一个节点(以前的 minion)工作。多个节点需要在 Kubernetes 之外完成功能性网络配置。尽管额外的 Kubernetes 配置需求是显而易见的。 + +Kubernetes 包提供了一些服务:kube-apiserver、kube-scheduler、kube-control -manager、kubelet、kube-proxy。这些服务由 systemd 管理,配置位于中心位置:`/etc/kubernetes`。 +我们将打破主机之间的服务。第一个主机,fed-master,将是 Kubernetes 主节点。该主节点将运行 kube-apiserver、kube-control-manager 和 kube-scheduler。 +此外,主服务器还将运行 *etcd* (如果 *etcd* 运行在不同的主机上就不需要了,但是本指南假设 *etcd* 和 Kubernetes 主服务器在同一主机上运行)。剩下的主机,fed-node 将是节点并运行 kubelet、proxy 和 docker。 + + + + +**系统信息:** + +主机: + +```conf +fed-master = 192.168.121.9 +fed-node = 192.168.121.65 +``` + + + +**准备主机:** + +* 在所有主机(fed-{master,node})上安装 Kubernetes 。这同时也会安装 docker。接着在 fed-master 上安装 etcd。本指南已经通过 Kubernetes-0.18 及更高版本的测试。 +* 在使用 RHEL 7.2 的 AWS EC2 上运行时,您需要通过编辑 `/etc/yum.repos.d/redhat-rhui.repo` 和更改 `enable=0to` 为 `enable=1` 来为 yum 启用 “extras” 仓库。 + +```shell +dnf -y install kubernetes +``` + + + +* 安装 etcd + +```shell +dnf -y install etcd +``` + + +* 将主机和节点添加到所有机器上的 `/etc/hosts` (如果主机名已经在 DNS 中,则不需要)。通过使用 ping 等实用程序,确保 fed-master 和 fed-node 之间的通信工作正常。 + + +```shell +echo "192.168.121.9 fed-master +192.168.121.65 fed-node" >> /etc/hosts +``` + + + +* 编辑 `/etc/kubernetes/config` (在所有主机上应该是相同的)来设置主服务器的名称: + +```shell +# 逗号分隔的 etcd 群集中的节点列表 +KUBE_MASTER="--master=http://fed-master:8080" +``` + + + +* 禁用主节点和子节点上的防火墙,因为 Docker 与其他防火墙规则管理器不兼容。请注意,默认的 Fedora Server 安装中不存在 iptables.service。 + +```shell +systemctl mask firewalld.service +systemctl stop firewalld.service + +systemctl disable iptables.service +systemctl stop iptables.service +``` + + + +**在主服务器上配置 Kubernetes 服务。** + +* 编辑 `/etc/kubernetes/apiserver`,包含以下内容。`service-cluster-ip-range` 的 IP 地址必须是未使用的地址块,同时也不能在其他任何地方使用。它们不需要路由或分配给任何东西。 + + + +```shell +# 本地服务器上所要监听的地址。 +KUBE_API_ADDRESS="--address=0.0.0.0" + +# 逗号在 ETCD 集群分离节点列表 +KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379" + +# 地址范围内使用的服务 +KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" + +# 添加你自己的! +KUBE_API_ARGS="" +``` + + + +* 编辑 `/etc/etcd/etcd.conf` 让 etcd 监听所有可用的 IP 地址,而不仅仅是 127.0.0.1。如果没有这样做,您可能会看到一个错误,例如 "connection refused"。 + +```shell +ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" +``` + + + +* 在主节点上启动适当的服务: + +```shell +for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do + systemctl restart $SERVICES + systemctl enable $SERVICES + systemctl status $SERVICES +done +``` + + + +**在节点上配置 Kubernetes 服务** + +***我们需要在节点上配置 kubelet。*** + +* 编辑 `/etc/kubernetes/kubelet`,加入以下内容: + + + + + +```shell +### +# Kubernetes kubelet(节点)的配置 + +# info 服务器要服务的地址(设置为 0.0.0.0 或 "" 用于所有接口) +KUBELET_ADDRESS="--address=0.0.0.0" + +# 可以留空,使用实际主机名 +KUBELET_HOSTNAME="--hostname-override=fed-node" + +# api-server 的位置 +KUBELET_ARGS="--cgroup-driver=systemd --kubeconfig=/etc/kubernetes/master-kubeconfig.yaml" + +``` + + + +* 编辑 `/etc/kubernetes/master-kubeconfig.yaml` 文件,添加以下信息: + +```yaml +kind: Config +clusters: +- name: local + cluster: + server: http://fed-master:8080 +users: +- name: kubelet +contexts: +- context: + cluster: local + user: kubelet + name: kubelet-context +current-context: kubelet-context +``` + + + +* 在节点(fed-node)上启动适当的服务。 + +```shell +for SERVICES in kube-proxy kubelet docker; do + systemctl restart $SERVICES + systemctl enable $SERVICES + systemctl status $SERVICES +done +``` + + +* 检查以确保集群在 fed-master 上可以看到 fed-node,并且它的状态更改为 _Ready_。 + +```shell +kubectl get nodes +NAME STATUS AGE VERSION +fed-node Ready 4h +``` + + + +* 删除节点: + +要从 Kubernetes 集群中删除 _fed-node_,应该在 fed-master 上运行以下命令(这只是演示用): + + +```shell +kubectl delete -f ./node.json +``` + + + +*到此为止!* + +**集群应该正在运行!创建测试 pod。** + +## 支持级别 + + + +IaaS 供应商 | 配置管理 | 操作系统| 网络 | 文档 | 合规 | 支持级别 + +-------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- +Bare-metal | custom | Fedora | _none_ | [文档](/docs/getting-started-guides/fedora/fedora_manual_config) | | 项目 + +有关所有解决方案的支持级别信息,请参见[解决方案表](/docs/getting-started-guides/#table-of-solutions)。 + + diff --git a/content/zh/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md b/content/zh/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md new file mode 100644 index 0000000000000..634167ccc4c21 --- /dev/null +++ b/content/zh/docs/getting-started-guides/fedora/flannel_multi_node_cluster.md @@ -0,0 +1,332 @@ +--- +reviewers: +- dchen1107 +- erictune +- thockin +title: Fedora (多节点) +--- + + + +{{< toc >}} + + +本文档描述了如何在多个主机上部署 Kubernetes 来建立一个多节点集群和 flannel 网络。遵循 fedora 入门指南设置 1 个主节点 (fed-master) + 和 2 个或更多节点。确保所有节点具有不同的名称(fed-node1、fed-node2 等等)和标签(fed-node1-label、fed-node2-label 等等),以避免 +任何冲突。还要确保 Kubernetes 主节点主机正在运行 etcd、kube-controller-manager、kube-scheduler 和 kube-apiserver 服务,节点正在 + 运行 docker、kube-proxy 和 kubelet 服务。现在在 Kubernetes 节点上安装 flannel。每个节点上的 flannel 配置 docker 使用的 overlay 网络。 + Flannel 在每个节点上运行,以设置一个唯一的 class-C 容器网络。 + + + +## 前提条件 + + +安装 Fedora 您需要两台或更多机器。 + + + +## 主节点设置 + + + +**在 Kubernetes 主节点上执行以下命令** + +* 在您当前的目录上的 fed-master 中通过创建一个 `flannel-config.json` 来配置 flannel。Flannel 在其他 overlay 网络后端选项中提供 udp 和 vxlan 。在本指南中,我们选择基于内核的 vxlan 后端。json 的内容为: + +```json +{ + "Network": "18.16.0.0/16", + "SubnetLen": 24, + "Backend": { + "Type": "vxlan", + "VNI": 1 + } +} +``` + +{{< note >}} + + +选择一个不在公共 IP 地址范围内的 IP 范围。 + +{{< /note >}} + + +将配置添加到 fed-master 上的 etcd 服务器。 + +```shell +etcdctl set /coreos.com/network/config < flannel-config.json +``` + + + +* 验证 fed-master 上的 etcd 服务器中是否存在该密钥。 + +```shell +etcdctl get /coreos.com/network/config +``` + + + +## 节点设置 + + + +**在所有 Kubernetes 节点上执行以下命令** + + + +安装 flannel 包 + +```shell +# dnf -y install flannel +``` + + + +编辑 flannel 配置文件 /etc/sysconfig/flanneld,如下所示: + + + +```shell +# Flanneld 配置选项 + +# etcd url 位置,将此指向 etcd 运行的服务器 +FLANNEL_ETCD="http://fed-master:2379" + +# etcd 配置的键。这是 flannel 查询的配置键 +# 用于地址范围分配 +FLANNEL_ETCD_KEY="/coreos.com/network" + +# 您想要传递的任何附加选项 +FLANNEL_OPTIONS="" +``` + +{{< note >}} + + +默认情况下,flannel 使用默认路由的接口。如果您有多个接口并且想要使用默认路由以外的接口,则可以将 "-iface=" 添加到 FLANNEL_OPTIONS。有关其他选项,请在命令行上运行 `flanneld --help`。 + +{{< /note >}} + + +启用 flannel 服务。 + +```shell +systemctl enable flanneld +``` + + +如果 docker 没有运行,那么启动 flannel 服务就足够了,跳过下一步。 + +```shell +systemctl start flanneld +``` + + +如果 docker 已经运行,则停止 docker,删除 docker bridge(docker0),启动 flanneld 并重新启动 docker,如下所示。另一种方法是重启系统(systemctl reboot)。 + +```shell +systemctl stop docker +ip link delete docker0 +systemctl start flanneld +systemctl start docker +``` + + + +## 测试集群和 flannel 配置 + + +现在检查节点上的接口。请注意,现在有一个 flannel.1 接口,docker0 和 flannel.1 接口的 ip 地址在同一个网络中。您会注意到 docker0 在上面配置的 IP 范围之外的每个 Kubernetes 节点上分配了一个子网(18.16.29.0/24,如下所示)。 正常运行的输出应如下所示: + + +```shell +# ip -4 a|grep inet + inet 127.0.0.1/8 scope host lo + inet 192.168.122.77/24 brd 192.168.122.255 scope global dynamic eth0 + inet 18.16.29.0/16 scope global flannel.1 + inet 18.16.29.1/24 scope global docker0 +``` + + +从集群中的任何节点,通过 curl 向 etcd 服务器发出查询来检查集群成员(仅显示部分输出 `grep -E "\{|\}|key|value`)。如果您设置了 1 个主节点和 3 个节点集群,您应该会看到每个节点都有一个块,显示分配给它们的子网。您可以通过输出中列出的 MAC 地址(VtepMAC)和 IP 地址(公共 IP) 将这些子网关联到每个节点。 + +```shell +curl -s http://fed-master:2379/v2/keys/coreos.com/network/subnets | python -mjson.tool +``` + +```json +{ + "node": { + "key": "/coreos.com/network/subnets", + { + "key": "/coreos.com/network/subnets/18.16.29.0-24", + "value": "{\"PublicIP\":\"192.168.122.77\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"46:f1:d0:18:d0:65\"}}" + }, + { + "key": "/coreos.com/network/subnets/18.16.83.0-24", + "value": "{\"PublicIP\":\"192.168.122.36\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"ca:38:78:fc:72:29\"}}" + }, + { + "key": "/coreos.com/network/subnets/18.16.90.0-24", + "value": "{\"PublicIP\":\"192.168.122.127\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"92:e2:80:ba:2d:4d\"}}" + } + } +} +``` + + +从所有节点,查看 `/run/flannel/subnet.env` 文件。这个文件是由 flannel 自动生成的。 + +```shell +# cat /run/flannel/subnet.env +FLANNEL_SUBNET=18.16.29.1/24 +FLANNEL_MTU=1450 +FLANNEL_IPMASQ=false +``` + + +此时,我们在 Kubernetes 主节点上运行了 etcd,在 Kubernetes 节点上运行了 flannel / docker。接下来的步骤是测试跨主机容器通信,这将确认 docker 和 flannel 配置正确。 + + +在任意两个节点上发出以下命令: + +```shell +# docker run -it fedora:latest bash +bash-4.3# +``` + + +您将会进入容器中。安装 iproute 和 iputils 包来安装 ip 和 ping 实用程序。由于一个[错误](https://bugzilla.redhat.com/show_bug.cgi?id=1142311),需要修改 ping 二进制文件的功能来处理"操作不允许"错误。 + +```shell +bash-4.3# dnf -y install iproute iputils +bash-4.3# setcap cap_net_raw-ep /usr/bin/ping +``` + + +现在记下第一个节点上的 IP 地址: + +```shell +bash-4.3# ip -4 a l eth0 | grep inet + inet 18.16.29.4/24 scope global eth0 +``` + + +还要注意另一个节点上的 IP 地址: + +```shell +bash-4.3# ip a l eth0 | grep inet + inet 18.16.90.4/24 scope global eth0 +``` + + +现在从第一个节点 ping 到另一个节点: + +```shell +bash-4.3# ping 18.16.90.4 +PING 18.16.90.4 (18.16.90.4) 56(84) bytes of data. +64 bytes from 18.16.90.4: icmp_seq=1 ttl=62 time=0.275 ms +64 bytes from 18.16.90.4: icmp_seq=2 ttl=62 time=0.372 ms +``` + + +现在,Kubernetes 多节点集群通过 flannel 设置 overlay 网络。 + + + +## 支持级别 + + + +IaaS 供应商 | 配置 管理 | 系统 | 网络 | 文档 | 标准 | 支持级别 +-------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- +Bare-metal | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) +libvirt | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) +KVM | custom | Fedora | flannel | [docs](/docs/getting-started-guides/fedora/flannel_multi_node_cluster/) | | Community ([@aveshagarwal](https://github.com/aveshagarwal)) + + + diff --git a/content/zh/docs/getting-started-guides/ubuntu.md b/content/zh/docs/getting-started-guides/ubuntu.md new file mode 100644 index 0000000000000..ae93616dfc61f --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu.md @@ -0,0 +1,63 @@ +--- +title: 在 Ubuntu 上运行 Kubernetes +content_template: templates/concept +--- + + +{{% capture overview %}} + +有多种方法可以在公有云、私有云以及裸金属上运行基于 Ubuntu 的 Kubernetes 集群。 +{{% /capture %}} + +{{% capture body %}} + +## Kubernetes Charmed 发行版(CDK) + + +[CDK](https://www.ubuntu.com/cloud/kubernetes) 是 Kubernetes 的一个发行版,作为开源应用程序建模器 Juju 的一组 *charms*。 + + +CDK 是附带了上游二进制文件的 Kubernetes 最新发行版,采用了一种支持快速简单部署的打包格式。它支持各种公有云和私有云,包括 AWS,GCE,Azure,Joyent,OpenStack,VMware 以及 Bare Metaland 本地部署。 + + +请参阅[官方文档](https://www.ubuntu.com/kubernetes/docs)获取详细信息。 + + +## MicroK8s + + +[MicroK8s](https://microk8s.io) 是 Kubernetes 的最小安装,旨在在本地运行。 + +它可以使用以下命令安装在 Ubuntu(或任何支持 snap 的操作系统)上: + +```shell +snap install microk8s --classic +``` + + +[MicroK8s 网站](https://microk8s.io/docs)上提供了完整的文档。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/_index.md b/content/zh/docs/getting-started-guides/ubuntu/_index.md new file mode 100644 index 0000000000000..e3c8a54e9fdd8 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/_index.md @@ -0,0 +1,140 @@ +--- +title: Ubuntu 上运行 Kubernetes +content_template: templates/concept +--- + + +{{% capture overview %}} + + +使用 Ubuntu 运行 Kubernetes 集群有多种方法。 这些页面阐释了如何在多种公共云、私有云和裸机的 Ubuntu 上部署 Kubernetes。 +{{% /capture %}} + +{{% capture body %}} + +## 官方 Ubuntu 指南 + +- [Kubernetes 的 Canonical 发行版](https://www.ubuntu.com/cloud/kubernetes) + +最新版 Kubernetes 上游二进制文件。 支持 AWS、GCE、Azure、Joyent、OpenStack、VMware、裸机和 localhost 部署。 + + +### 快速入门 + +[conjure-up](http://conjure-up.io/) 提供了在多种云和裸机的 Ubuntu 上部署 Kubernetes 的最快方法。它提供了用户友好的界面,提示您提供云凭据和配置选项 + +适用于 Ubuntu 16.04 及更高版本: + +``` +sudo snap install conjure-up --classic +# 如果您刚刚安装了 snap 工具,可能需要重新登录。 +conjure-up kubernetes +``` + + + +以及用于 macOS 的 Homebrew: + +``` +brew install conjure-up +conjure-up kubernetes +``` + + + +### 操作指南 + +这些是用户在生产中运行 Kubernetes 的更深入的指南: + + - [安装](/docs/getting-started-guides/ubuntu/installation/) + - [验证](/docs/getting-started-guides/ubuntu/validation/) + - [备份](/docs/getting-started-guides/ubuntu/backups/) + - [升级](/docs/getting-started-guides/ubuntu/upgrades/) + - [缩放](/docs/getting-started-guides/ubuntu/scaling/) + - [日志](/docs/getting-started-guides/ubuntu/logging/) + - [监控](/docs/getting-started-guides/ubuntu/monitoring/) + - [网络](/docs/getting-started-guides/ubuntu/networking/) + - [安全](/docs/getting-started-guides/ubuntu/security/) + - [存储](/docs/getting-started-guides/ubuntu/storage/) + - [故障排除](/docs/getting-started-guides/ubuntu/troubleshooting/) + - [退役](/docs/getting-started-guides/ubuntu/decommissioning/) + - [操作因素](/docs/getting-started-guides/ubuntu/operational-considerations/) + - [词汇表](/docs/getting-started-guides/ubuntu/glossary/) + + + + +## 第三方产品集成 + + - [Rancher](/docs/getting-started-guides/ubuntu/rancher/) + +## 开发者指南 + + - [Localhost 使用 LXD](/docs/getting-started-guides/ubuntu/local/) + + + +## 如何找到我们 + +我们通常关注以下 Slack 频道: + +- [kubernetes-users](https://kubernetes.slack.com/messages/kubernetes-users/) +- [kubernetes-novice](https://kubernetes.slack.com/messages/kubernetes-novice/) +- [sig-cluster-lifecycle](https://kubernetes.slack.com/messages/sig-cluster-lifecycle/) +- [sig-cluster-ops](https://kubernetes.slack.com/messages/sig-cluster-ops/) +- [sig-onprem](https://kubernetes.slack.com/messages/sig-onprem/) + +而且我们会查看 Kubernetes 邮件列表。 +{{% /capture %}} + diff --git a/content/zh/docs/getting-started-guides/ubuntu/backups.md b/content/zh/docs/getting-started-guides/ubuntu/backups.md new file mode 100644 index 0000000000000..7fa1213a5da5e --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/backups.md @@ -0,0 +1,189 @@ +--- +title: 备份 +content_template: templates/task +--- + +{{% capture overview %}} + + +Kubernetes 集群的状态信息保存在 etcd 数据库中。 +本文将要展示如何对 Canonical 发行版的 Kubernetes 中所带有的 etcd 进行备份和恢复。 +至于如何对通常保存在持久卷上的应用数据进行备份,超出了本文的讨论范围。 + +{{% /capture %}} + +{{% capture prerequisites %}} + +本文假设您有一个 Juju 部署的集群。 +{{% /capture %}} + +{{% capture steps %}} + +## 快照 etcd 中的数据 + + + +etcd charm 的 `snapshot` 操作能够让操作员给正在运行的集群数据建立快照,快照数据可用于复制、备份或者迁移到一个新的集群中。 + + juju run-action etcd/0 snapshot + +这条命令会在 `/home/ubuntu/etcd-snapshots` 默认路径下建立一个快照。 + + +## 恢复 etcd 数据 + + + +etcd charm 能够通过 `restore` 操作从一个集群数据快照中恢复集群数据。 +这里有些注意事项,而且是恢复集群的唯一办法:集群当前只能有一个成员。 +所以最好是使用 etcd charm 来部署一个新的集群,而不必添加任何新的单元。 + +``` +juju deploy etcd new-etcd +``` + + +上面的命令将会部署一个单独的 etcd 单元,'new-etcd'。 + +``` +juju run-action etcd/0 restore target=/mnt/etcd-backups +``` + + + +当恢复操作完成后,评估一下集群的健康状态。如果集群运行良好,就可以按照您的需求来扩展应用程序规模。 + +- **参数** target: 保存现有数据的目的路径。 +- **参数** skip-backup: 不要备份任何现有的数据。 + + + + +## 迁移 etcd 集群 +通过使用上述的 `snapshot` 和 `restore` 操作,就能很容易地迁移 etcd 集群。 + + +**第一步:** 给现有的集群建立快照。这个已经封装在 `snapshot` 操作中。 + +``` +juju run-action etcd/0 snapshot +``` + + +结果: + +``` +Action queued with id: b46d5d6f-5625-4320-8cda-b611c6ae580c +``` + + +**第二步:** 检查操作状态,以便您能抓取快照并且验证校验和。 +您可以直接使用 `copy.cmd` 中的结果来下载您刚刚创建的快照数据,`copy.cmd` 中的结果可以直接复制/粘贴使用。 + + +从节点上下载刚刚创建的快照数据并且验证 sha256sum 校验和 + +``` +juju show-action-output b46d5d6f-5625-4320-8cda-b611c6ae580c +``` + + +结果: + +``` +results: + copy: + cmd: juju scp etcd/0:/home/ubuntu/etcd-snapshots/etcd-snapshot-2016-11-09-02.41.47.tar.gz + . + snapshot: + path: /home/ubuntu/etcd-snapshots/etcd-snapshot-2016-11-09-02.41.47.tar.gz + sha256: 1dea04627812397c51ee87e313433f3102f617a9cab1d1b79698323f6459953d + size: 68K +status: completed +``` + + +将数据快照拷到本地,然后检查 sha256sum。 + +``` +juju scp etcd/0:/home/ubuntu/etcd-snapshots/etcd-snapshot-2016-11-09-02.41.47.tar.gz . +sha256sum etcd-snapshot-2016-11-09-02.41.47.tar.gz +``` + + +**第三步:** 部署新的集群 leader 节点,并加载快照数据: + +``` +juju deploy etcd new-etcd --resource snapshot=./etcd-snapshot-2016-11-09-02.41.47.tar.gz +``` + + +**第四步:** 使用在第三步中的快照数据来重新初始化 master: + +``` +juju run-action new-etcd/0 restore +``` + +{{% /capture %}} + +{{% capture discussion %}} + +## 已知的局限 + + +#### 丢失 PKI 警告 + + + +如果销毁了 leader - 在状态栏通过 `*` 来标识,那么所有的 TLS pki 警告都将会丢失。 +在请求和注册证书的单元之外,将不会有 PKI 迁移发生。 + +{{< caution >}} + + +**警告:** 如果误管理这项配置,将会导致您无法从外部访问集群, +并且很可能会破坏现有的部署,出现 x509 证书验证相关的异常问题,这些都会对服务器和客户端造成影响。 + +{{< /caution >}} + + +#### 在一个已经扩展的集群上进行快照数据恢复 + + + +在一个已经扩展的集群上进行快照数据恢复,将会导致集群损坏。 +etcd 在节点启动时开始集群管理,并且将状态保存在 etcd 中。 +在快照数据的恢复阶段,会初始化一个新的集群 ID,并且丢弃其它 peer 节点以保证快照数据的恢复。 +请严格遵照上述集群迁移中的恢复操作来进行操作。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/decommissioning.md b/content/zh/docs/getting-started-guides/ubuntu/decommissioning.md new file mode 100644 index 0000000000000..9956c0f84c107 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/decommissioning.md @@ -0,0 +1,103 @@ +--- +title: 销毁 +content_template: templates/task +--- + + + + +{{% capture overview %}} + +本页将展示如何销毁一个集群。 +{{% /capture %}} + + +{{% capture prerequisites %}} + +本页假设有一个使用 Juju 部署的、正在运行的集群。 + +{{< warning >}} + +当您到达这一步时,您应该已经对集群的相关内容进行了备份;这部分将彻底销毁一个集群。 +{{< /warning >}} + +{{% /capture %}} + +{{% capture steps %}} + +## 破坏 Juju 模型 + + + +建议使用各自的模型来相应地部署 Kubernetes 集群, +以便各个环境之间能够界限分明。 +如果想要删除一个集群,首先需要通过 `juju list-models` 命令找到其对应的模型。 +控制器为其自身预留了 `admin` 这个模型。 +如果没有命名模型,则模型名可能会显示为 `default`。 + +``` +$ juju list-models +Controller: aws-us-east-2 + +Model Cloud/Region Status Machines Cores Access Last connection +controller aws/us-east-2 available 1 2 admin just now +my-kubernetes-cluster* aws/us-east-2 available 12 22 admin 2 minutes ago +``` + + +销毁模型,模型内的集群也随之被销毁: + + juju destroy-model my-kubernetes-cluster + +``` +$ juju destroy-model my-kubernetes-cluster +WARNING! This command will destroy the "my-kubernetes-cluster" model. +This includes all machines, applications, data and other resources. + +Continue [y/N]? y +Destroying model +Waiting on model to be removed, 12 machine(s), 10 application(s)... +Waiting on model to be removed, 12 machine(s), 9 application(s)... +Waiting on model to be removed, 12 machine(s), 8 application(s)... +Waiting on model to be removed, 12 machine(s), 7 application(s)... +Waiting on model to be removed, 12 machine(s)... +Waiting on model to be removed... +$ +``` + + +这将会彻底破坏并销毁所有节点。 +运行 `juju status` 命令可以确认所有节点是否已经被销毁。 + + +如果使用的是公有云,命令将会终止所有的实例。 +如果使用的是 MAAS 裸机,命令将会释放所有的节点,(可能)清空磁盘,关闭机器, +然后将节点资源返回到可用的机器池中。 + + +## 清理控制器 + + +如果控制器没有其它的用途,还需要删除控制器实例: + +``` +$ juju list-controllers +Use --refresh flag with this command to see the latest information. + +Controller Model User Access Cloud/Region Models Machines HA Version +aws-us-east-2* - admin superuser aws/us-east-2 2 1 none 2.0.1 + +$ juju destroy-controller aws-us-east-2 +WARNING! This command will destroy the "aws-us-east-2" controller. +This includes all machines, applications, data and other resources. + +Continue? (y/N):y +Destroying controller +Waiting for hosted model resources to be reclaimed +All hosted models reclaimed, cleaning up controller machines +$ +``` +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/glossary.md b/content/zh/docs/getting-started-guides/ubuntu/glossary.md new file mode 100644 index 0000000000000..43528245ab251 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/glossary.md @@ -0,0 +1,50 @@ +--- +title: 词汇与术语 +content_template: templates/concept +--- + + + + + +{{%capture overview%}} +本页介绍了用 Juju 部署 Kubernetes 时使用的一些术语。 +{{%/ capture%}} + +{{%capture body%}} + + + +**controller** - 云环境的管理节点。通常,每个域(Region)都有一个 controller,在高可用环境中有更多 controller。每个 controller 负责管理给定环境中的所有后续 model。Controller 中包含 Juju API 服务器及其底层数据库。 + +**model** - 定义 Deployments 的一系列 charms 及其关系的集合。model 之中包括 machine 和更小的 unit。每个 controller 可以托管多个 model。出于管理和隔离的原因,建议将 Kubernetes 集群分成独立的 model。 + +**charm** - 每个 charm 对应一个 Service 的定义,包括其元数据、与其他服务间的依赖关系、所需的包和应用管理逻辑。 +其中包含部署 Kubernetes 集群的所有操作知识。内置的 charms 例子有 `kubernetes-core`、`easyrsa`、`flannel` 和 `etcd` 等。 + +**unit** - 对应某 Service 的给定实例。每个 unit 可能会也可能不会耗尽某指定机器上的所有资源。多个 unit 可能部署在同一台机器上。例如,您可能在一台机器上运行 `kubernetes-worker` 和 `etcd` 以及 `easyrsa` unit,但它们是基于不同服务的三个独立的 unit。 + +**machine** - 物理节点,可以是裸机节点,也可以是云提供商提供的虚拟机。 +{{%/ capture%}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/installation.md b/content/zh/docs/getting-started-guides/ubuntu/installation.md new file mode 100644 index 0000000000000..93d61d742412e --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/installation.md @@ -0,0 +1,542 @@ +--- +reviewers: +- caesarxuchao +- erictune +title: 用 Juju 搭建 Kubernetes +content_template: templates/task +--- + + + + + +{% capture overview %} +Ubuntu 16.04 已公开 [Kubernetes 的 Canonical 发行版 ](https://www.ubuntu.com/cloud/kubernetes), 一套为生产环境设计的 Kubernetes 上游版本。本文将为您演示如何部署集群。 +{% endcapture %} + + + +{{% capture prerequisites %}} +- 一个可用的 [Juju 客户端](https://jujucharms.com/docs/2.3/reference-install);不一定要是 Linux 机器,也可以是 Windows 或 OSX。 +- 一个[受支持的云](#cloud-compatibility)。 + - 裸机部署可以通过 [MAAS](http://maas.io) 实现。 配置指南参见 [MAAS 文档](http://maas.io/docs/)。 + - OpenStack 部署目前只在 Icehouse 及更新版本上测试通过。 +- 下面任一一种选项: + - 可以网络访问以下站点 + - *.jujucharms.com + - gcr.io + - github.com + - 访问 Ubuntu 镜像源(公共的或私有的) + - 通过[这些](https://github.com/juju-solutions/bundle-canonical-kubernetes/wiki/Running-CDK-in-a-restricted-environment)步骤准备好离线部署。 +{{% /capture %}} + + + +{{% capture steps %}} +## 部署概述 + +开箱即用的部署由以下组件构成,部署在 9 台机器上: + +- Kubernetes (自动化部署,运营及伸缩) + - 具有一个主节点和三个工作节点的四节点 Kubernetes 集群。 + - 使用 TLS 实现组件间的安全通信。 + - Flannel 软件定义网络 (SDN) 插件 + - 一个负载均衡器以实现 kubernetes-master 的高可用 (实验阶段) + - 可选的 Ingress 控制器(在工作节点上) + - 可选的 Dashboard 插件(在主节点上),包含实现集群监控的 Heapster 插件 +- EasyRSA + - 扮演证书授权机构的角色,向集群中的组件提供自签名证书 +- ETCD (分布式键值存储) + - 三节点的集群达到高可靠性。 + + + +Juju Kubernetes 工作由 Canonical Ltd(https://www.canonical.com/) 的 Big Software 团队整理,欢迎对我们的工作给出反馈意见。 +如果发现任何问题,请提交相应的 [Issue 到跟踪系统](https://github.com/juju-solutions/bundle-canonical-kubernetes),以便我们解决。 + + + +## 支持级别 + +IaaS 提供商 | 配置管理 | 系统 | 网络 | 文档 | 符合 | 支持级别 +-------------------- | ------------ | ------ | ---------- | --------------------------------------------- | ---------| ---------------------------- +Amazon Web Services (AWS) | Juju | Ubuntu | flannel, calico* | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +OpenStack | Juju | Ubuntu | flannel, calico | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +Microsoft Azure | Juju | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +Google Compute Engine (GCE) | Juju | Ubuntu | flannel, calico | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +Joyent | Juju | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +Rackspace | Juju | Ubuntu | flannel | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +VMWare vSphere | Juju | Ubuntu | flannel, calico | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) +Bare Metal (MAAS) | Juju | Ubuntu | flannel, calico | [docs](/docs/getting-started-guides/ubuntu) | | [Commercial](https://ubuntu.com/cloud/kubernetes), [Community](https://github.com/juju-solutions/bundle-kubernetes-core) + + + + +有关所有解决方案的支持级别信息,请参见[解决方案表](/docs/getting-started-guides/#table-of-solutions)。 + +## 安装选项 + +可以通过下面任一一种方式启动集群:[conjure-up](#conjure-up) or [juju 部署](#juju-deploy)。Conjure-up 只是一个对 juju 的简易封装,简化了安装的过程。正因为如此,这也是推荐的安装方法。 + +可以在 [众多不同的公有云](#cloud-compatibility),私有 OpenStack 云,或者是原始的裸机集群上部署集群软件。通过 [MAAS](http://maas.io) 实现裸机部署。 + +## Conjure-up + +通过 conjure-up 来安装 Kubernetes, 只需要运行下面的命令,然后根据提示做选择: + +``` +sudo snap install conjure-up --classic +conjure-up kubernetes +``` + +## Juju 部署 + +### 配置 Juju 使用您的云提供商 + +确定所要部署的云之后,按照[云安装界面](https://jujucharms.com/docs/devel/getting-started)来配置、部署到该云。 + +加载[云凭证](https://jujucharms.com/docs/2.3/credentials)来选择、使用相应的云。 + + + +在本例中 + +``` +juju add-credential aws +credential name: my_credentials +select auth-type [userpass, oauth, etc]: userpass +enter username: jorge +enter password: ******* +``` + +也可以通过 `juju autoload-credentials` 命令自动加载常用的云凭证,该命令将自动从每个云的默认文件和环境变量中导入凭据信息。 + + + +接下来,我们需要启动一个控制器来管理集群。您需要确定所要启动的云,地区以及控制器节点的名字: + +``` +juju update-clouds # 这个命令可以确保客户端上所有最新的区域是最新的 +juju bootstrap aws/us-east-2 +``` +或者,另外一个例子,这次是在 Azure 上: + +``` +juju bootstrap azure/westus2 +``` + + + +如果您看到下面的错误信息,很可能默认的 Azure VM (Standard D1 v2 [1 vcpu, 3.5 GB memory]) 并不在当前的 Azure 地区。 +``` +ERROR failed to bootstrap model: instance provisioning failed (Failed) +``` + + + + +您需要为部署到的每个云或区域分配一个控制器节点。更多信息参见[控制器文档](https://jujucharms.com/docs/2.3/controllers)。 + +请注意,每个控制器可以在给定的云或区域中管理多个 Kubernetes 集群。 + + + +## 启动 Kubernetes 集群 + +以下命令将部署 9-节点的初始集群。执行速度取决于您所要部署到的云的性能: + +``` +juju deploy canonical-kubernetes +``` + +执行完此命令后,云将启动实例并开始部署过程。 + + + +## 监控部署 + +`juju status` 命令提供集群中每个单元的信息。`watch -c juju status --color` 命令可以获取集群部署的实时状态。 +当所有的状态是绿色并且“空闲”时,表示集群处于待用状态: + + juju status + +输出结果: + +``` +Model Controller Cloud/Region Version SLA +conjure-canonical-kubern-f48 conjure-up-aws-650 aws/us-east-2 2.3.2 unsupported + +App Version Status Scale Charm Store Rev OS Notes +easyrsa 3.0.1 active 1 easyrsa jujucharms 27 ubuntu +etcd 2.3.8 active 3 etcd jujucharms 63 ubuntu +flannel 0.9.1 active 4 flannel jujucharms 40 ubuntu +kubeapi-load-balancer 1.10.3 active 1 kubeapi-load-balancer jujucharms 43 ubuntu exposed +kubernetes-master 1.9.3 active 1 kubernetes-master jujucharms 13 ubuntu +kubernetes-worker 1.9.3 active 3 kubernetes-worker jujucharms 81 ubuntu exposed + +Unit Workload Agent Machine Public address Ports Message +easyrsa/0* active idle 3 18.219.190.99 Certificate Authority connected. +etcd/0 active idle 5 18.219.56.23 2379/tcp Healthy with 3 known peers +etcd/1* active idle 0 18.219.212.151 2379/tcp Healthy with 3 known peers +etcd/2 active idle 6 13.59.240.210 2379/tcp Healthy with 3 known peers +kubeapi-load-balancer/0* active idle 1 18.222.61.65 443/tcp Loadbalancer ready. +kubernetes-master/0* active idle 4 18.219.105.220 6443/tcp Kubernetes master running. + flannel/3 active idle 18.219.105.220 Flannel subnet 10.1.78.1/24 +kubernetes-worker/0 active idle 2 18.219.221.98 80/tcp,443/tcp Kubernetes worker running. + flannel/1 active idle 18.219.221.98 Flannel subnet 10.1.38.1/24 +kubernetes-worker/1* active idle 7 18.219.249.103 80/tcp,443/tcp Kubernetes worker running. + flannel/2 active idle 18.219.249.103 Flannel subnet 10.1.68.1/24 +kubernetes-worker/2 active idle 8 52.15.89.16 80/tcp,443/tcp Kubernetes worker running. + flannel/0* active idle 52.15.89.16 Flannel subnet 10.1.73.1/24 + +Machine State DNS Inst id Series AZ Message +0 started 18.219.212.151 i-065eab4eabc691b25 xenial us-east-2a running +1 started 18.222.61.65 i-0b332955f028d6281 xenial us-east-2b running +2 started 18.219.221.98 i-0879ef1ed95b569bc xenial us-east-2a running +3 started 18.219.190.99 i-08a7b364fc008fc85 xenial us-east-2c running +4 started 18.219.105.220 i-0f92d3420b01085af xenial us-east-2a running +5 started 18.219.56.23 i-0271f6448cebae352 xenial us-east-2c running +6 started 13.59.240.210 i-0789ef5837e0669b3 xenial us-east-2b running +7 started 18.219.249.103 i-02f110b0ab042f7ac xenial us-east-2b running +8 started 52.15.89.16 i-086852bf1bee63d4e xenial us-east-2c running + +Relation provider Requirer Interface Type Message +easyrsa:client etcd:certificates tls-certificates regular +easyrsa:client kubeapi-load-balancer:certificates tls-certificates regular +easyrsa:client kubernetes-master:certificates tls-certificates regular +easyrsa:client kubernetes-worker:certificates tls-certificates regular +etcd:cluster etcd:cluster etcd peer +etcd:db flannel:etcd etcd regular +etcd:db kubernetes-master:etcd etcd regular +kubeapi-load-balancer:loadbalancer kubernetes-master:loadbalancer public-address regular +kubeapi-load-balancer:website kubernetes-worker:kube-api-endpoint http regular +kubernetes-master:cni flannel:cni kubernetes-cni subordinate +kubernetes-master:kube-api-endpoint kubeapi-load-balancer:apiserver http regular +kubernetes-master:kube-control kubernetes-worker:kube-control kube-control regular +kubernetes-worker:cni flannel:cni kubernetes-cni subordinate +``` + + + +## 与集群的交互 + +部署完集群后,您可以在任意一个 kubernetes-master 或 kubernetes-worker 节点取得集群的控制权。 + +如果您没有使用 conjure-up,那么您需要先将凭据和客户端程序下载到本地工作站上: + +创建 kubectl 配置信息目录。 + +``` +mkdir -p ~/.kube +``` + +将 kubeconfig 文件复制到默认位置。 + +``` +juju scp kubernetes-master/0:config ~/.kube/config +``` + + + +下一步是在本地机器上安装 kubectl 客户端。在 Ubuntu 上推荐的安装方式是使用 kubectl snap ([/docs/tasks/tools/install-kubectl/#install-with-snap-on-ubuntu](/docs/tasks/tools/install-kubectl/#install-with-snap-on-ubuntu))。 + +可以运行下面的命令便可以控制 kubernetes 集群了: + +``` +sudo snap install kubectl --classic +``` + +这条命令会安装和部署 kubectl 程序。安装完成后,您可能需要重启命令窗口(因为 $PATH 已经被更新)。 + + + +查询集群: + kubectl cluster-info + +输出结果: + +``` +Kubernetes master is running at https://52.15.104.227:443 +Heapster is running at https://52.15.104.227:443/api/v1/namespaces/kube-system/services/heapster/proxy +KubeDNS is running at https://52.15.104.227:443/api/v1/namespaces/kube-system/services/kube-dns/proxy +Grafana is running at https://52.15.104.227:443/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy +InfluxDB is running at https://52.15.104.227:443/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy +``` + + + +## 为集群垂直扩容 + +需要更大的 Kubernetes 节点?通过使用 Juju 的**约束**,您可以轻松地请求到不同大小的云资源。 +通过 Juju 请求创建的任意系统,您都可以为它们增加 CPU 和内存(RAM)。 +这使您可以对 Kubernetes 集群进行调优以适应工作负载。 +藉由 bootstrap 命令的参数或使用独立的 `juju constraints` 命令都可以做到这点。详情参见[和机器相关的 Juju 文档](https://jujucharms.com/docs/2.3/charms-constraints) + + + +## 为集群集群水平扩容 + +需要更多的工作节点?只需添加一些 unit: + +```shell +juju add-unit kubernetes-worker +``` + +或者一次添加多个: + +```shell +juju add-unit -n3 kubernetes-worker +``` +您也可以为特定实例类型或者特定机器的设置约束。更多信息请参见[约束文档](https://jujucharms.com/docs/stable/reference-constraints)。 +接下来举一些例子。请注意,诸如 `cores` 和 `mem` 这样的通用约束在各云之间的可移植性是比较高的。 +在本例中,我们从 AWS 申请一个特定的实例类型: + +```shell +juju set-constraints kubernetes-worker instance-type=c4.large +juju add-unit kubernetes-worker +``` + +为提升键值存储的容错能力,您也可以扩展 etcd charm: + +```shell +juju add-unit -n3 etcd +``` + +强烈建议运行奇数个 unit 以支持法定人数票选。 + + + +## 销毁集群 + +如果您是使用 conjure-up 创建的集群,通过 `conjure-down` 便可以完成销毁过程。 +如果是直接使用的 juju,你可以通过销毁 juju 模型或控制器来销毁集群。 +使用 `juju switch` 命令获取当前控制器的名字: + +```shell +juju switch +juju destroy-controller $controllername --destroy-all-models +``` + +这将关闭并终止该云上所有正在运行的实例。 +{{% /capture %}} + +{{% capture discussion %}} + + + +{{% capture discussion %}} +## 更多信息 + +Ubuntu Kubernetes 的部署通过名为 charms 的开源运维工具实现,这类工具也称作运维即代码(Operations as Code)。 +这些 charms 以层的方式组装,从而使代码更小,更专注于 Kubernetes 及其组件的操作。 + +Kubernetes 的层和 Bundle 可以在 github.com 的 `kubernetes` 项目中找到: + +- [Bundle 的地址](https://git.k8s.io/kubernetes/cluster/juju/bundles) +- [Kubernetes charm 层的地址](https://git.k8s.io/kubernetes/cluster/juju/layers) +- [Canonical Kubernetes 主页](https://jujucharms.com/kubernetes) +- [主要的 issue tracker](https://github.com/juju-solutions/bundle-canonical-kubernetes) + +欢迎提供功能需求,错误报告,pull request和反馈意见。 +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/local.md b/content/zh/docs/getting-started-guides/ubuntu/local.md new file mode 100644 index 0000000000000..1744114ae19c8 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/local.md @@ -0,0 +1,118 @@ +--- +title: 通过 LXD 实现 Kubernetes 本地开发 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +在本地运行 Kubernetes 比在公有云上部署和移除集群具有明显的开发优势,如更低的成本和更快的迭代。 +理想情况下,Kubernetes 开发人员可以在本地容器内产生所有必需的节点,并在提交新配置时测试它们。 +本文将展示如何将集群部署到本地机器的 LXD 容器上。 + +{{% /capture %}} + + + +在本地机器上使用 [LXD](https://linuxcontainers.org/lxd/) 的目的是为了模拟用户在云或裸机中部署的环境。每个节点都被视为一台机器,具有与生产环境相同的特性。 每个节点都是一个单独的容器,它在里面运行 Docker 容器和 `kubectl`(更多信息请参阅 [集群简介](/docs/tutorials/kubernetes-basics/cluster-intro/))。 + +{{% capture prerequisites %}} + + + +安装 [conjure-up](http://conjure-up.io/),这是一个用来部署大型软件的工具。 +将当前用户添加到 `lxd` 用户组中。 + +``` +sudo snap install conjure-up --classic +sudo usermod -a -G lxd $(whoami) +``` + + + +注意:如果 conjure-up 要求您在 LXD 上 "配置一个 ipv6 子网",请选择 NO。目前还不支持在 Juju/LXD 上使用 ipv6。 +{% endcapture %} + +{{% capture steps %}} + + + +## 部署 Kubernetes + + +通过以下命令启动部署: + + conjure-up kubernetes + + + +对于本教程,我们将会创建一个新的控制器 - 选择 `localhost` 云类型: + +![选择云类型](/images/docs/ubuntu/00-select-cloud.png) + + + +部署应用: + +![部署应用](/images/docs/ubuntu/01-deploy.png) + + + +等待 Juju 引导结束: + +![引导](/images/docs/ubuntu/02-bootstrap.png) + + + +等待应用被完全部署: + +![等待](/images/docs/ubuntu/03-waiting.png) + + + +执行最终的后处理步骤,来自动配置 Kubernetes 环境: + +![后处理](/images/docs/ubuntu/04-postprocessing.png) + + + +查看最终的摘要信息: + +![最终的摘要](/images/docs/ubuntu/05-final-summary.png) + + + +## 访问集群 + +您可以通过运行以下命令来访问 Kubernetes 集群: + + kubectl --kubeconfig=~/.kube/config + + +或者如果您已经运行过一次,它将创建一个新的配置文件,如摘要信息所示。 + + kubectl --kubeconfig=~/.kube/config.conjure-up + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/logging.md b/content/zh/docs/getting-started-guides/ubuntu/logging.md new file mode 100644 index 0000000000000..341882002129c --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/logging.md @@ -0,0 +1,79 @@ +--- +title: 日志 +content_template: templates/task +--- + + + +{{% capture overview %}} + +本文将说明日志在 Juju 部署的集群中是如何工作的。 +{{% /capture %}} + +{{% capture prerequisites %}} + +本文假设你已经有一个可用的 Juju 部署的集群。 +{{% /capture %}} + +{{% capture steps %}} + +## 代理日志 + + +`juju debug-log` 命令可以显示集群中每一个节点上运行的 Juju 代理所汇总的日志结果。 +它可以帮助确定为何某个节点没有被部署或者是处于错误的状态。这些代理日志被存放在每个节点的 `/var/lib/juju/agents` 路径下。 + + +更多信息参见[Juju 文档](https://jujucharms.com/docs/stable/troubleshooting-logs) + + + +## 管理日志级别 + + +Juju 中默认的日志级别是 model 级别。不过,你可以随时调整它: + +``` +juju add-model k8s-development --config logging-config='=DEBUG;unit=DEBUG' +``` + + +然后在你的生态环境下的 k8s 模型进行配置 + +``` +juju model-config -m k8s-production logging-config='=ERROR;unit=ERROR' +``` + + +另外,所有控制器上的 jujud 守护进程默认使用 debug 级别。如果想要移除这种行为,编辑控制器节点上的 ```/var/lib/juju/init/jujud-machine-0/exec-start.sh``` 文件并注释掉 ```--debug``` 选项。 + + +修改之后,如下所示: + +``` +#!/usr/bin/env bash + +# Set up logging. +touch '/var/log/juju/machine-0.log' +chown syslog:syslog '/var/log/juju/machine-0.log' +chmod 0600 '/var/log/juju/machine-0.log' +exec >> '/var/log/juju/machine-0.log' +exec 2>&1 + +# Run the script. +'/var/lib/juju/tools/machine-0/jujud' machine --data-dir '/var/lib/juju' --machine-id 0 # --debug +``` + + +然后运行下面的命令,重启服务: + +``` +sudo systemctl restart jujud-machine-0.service +``` + + +Juju 中更多和日志与其它模型设置相关的信息请参考[官方文档](https://jujucharms.com/docs/stable/models-config)。 +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/monitoring.md b/content/zh/docs/getting-started-guides/ubuntu/monitoring.md new file mode 100644 index 0000000000000..8f437d55dd821 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/monitoring.md @@ -0,0 +1,234 @@ +--- +title: 监控 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +本文将介绍如何将不同的日志解决方案连到已经用 Juju 部署好的 Kubernetes 集群上。 + +{{% /capture %}} + +{{% capture prerequisites %}} + + +本文假设你有一个用 Juju 部署好了的 Kubernetes 集群。 + +{{% /capture %}} + +{{% capture steps %}} + + + +## 连接 Datadog + + + +Datadog 是一个 SaaS 方案,包含了对很多不同类型的应用集成的支持,例如,Kubernetes 和 etcd。 +在提供商业版本的同时,也支持通过如下方式免费使用。 +部署一个带有现成的 Databox 的 Kubernetes 集群: + +``` +juju deploy canonical-kubernetes-datadog +``` + + +### 安装 Datadog + + +首先, 从 Juju 的 Charm Store 下载部署最新版本的 Datadog : + +``` +juju deploy datadog +``` + + + +使用在 [Datadog dashboard]() 上的 api-key 来配置 Datadog。 +将 `XXXX` 配置为你的 API 密钥。 + +``` +juju configure datadog api-key=XXXX +``` + + + +最后, 将 `datadog` 绑定到需要监控的所有应用上。例如:kubernetes-master, kubernetes-worker, and etcd: + +``` +juju add-relation datadog kubernetes-worker +juju add-relation datadog kubernetes-master +juju add-relation datadog etcd +``` + + +## 连接 Elastic 栈 + + + +Elastic 栈,正规地说是 "ELK" 栈, 指的是 ElasticSearch 和日志收集,监控,dashboard 的套件. +部署带有现成的 elastic 栈的 Kubernetes 集群命令如下: + +``` +juju deploy canonical-kubernetes-elastic +``` + + +### 初装 ElasticSearch + + + +首先, 从 Juju 的 Charm store 下载、部署最新版本的 ElasticSearch, Kibana, Filebeat 和 Topbeat: + + + +命令行如下: + +``` +juju deploy beats-core +``` + + + +此外,如果你要定制部署,或手工安装,可使用以下命令: + +``` +juju deploy elasticsearch +juju deploy kibana +juju deploy filebeat +juju deploy topbeat + +juju add-relation elasticsearch kibana +juju add-relation elasticsearch topbeat +juju add-relation elasticsearch filebeat +``` + + + +最后将 filebeat 和 topbeat 连接到所要监控的应用上。 +例如:kubernetes-master 和 kubernetes-worker: + +``` +juju add-relation kubernetes-master topbeat +juju add-relation kubernetes-master filebeat +juju add-relation kubernetes-worker topbeat +juju add-relation kubernetes-worker filebeat +``` + + +### 已装 ElasticSearch 集群 + + + +如果已有一个 ElasticSearch 集群已经存在的情况下, +你可以使用下面的方式来连接和使用它而不是重新创建一个单独的新集群。 +首先部署 filebeat 和 topbeat 两个组件: + +``` +juju deploy filebeat +juju deploy topbeat +``` + + + +按照如下方式可配置 filebeat 和 topbeat 对接 ElasticSearch 集群, +将 `255.255.255.255` 替换成自己配置的IP。 + +``` +juju configure filebeat elasticsearch=255.255.255.255 +juju configure topbeat elasticsearch=255.255.255.255 +``` + + + +使用上面的命令,将 topbeat 和 filebeat 连接到需要监控的应用上。 + + + + +## 连接 Nagios + + + +Nagios 在每个节点上,使用 Nagions 远程执行插件协议 (NRPE 协议)作为代理 +来收集节点里和健康、应用相关的详细信息。 + + + +### 初装 Nagios + + + +首先, 从 Juju 的 Charm store 部署最新版本的 Nagois 和 NRPE: + +``` +juju deploy nagios +juju deploy nrpe +``` + + +将 Nagois 连接到 NRPE 上 + +``` +juju add-relation nagios nrpe +``` + + + +最后,将 NRPE 添加到所有需要部署的应用, +例如,`kubernetes-master`, `kubernetes-worker`, `etcd`, `easyrsa`, 和 `kubeapi-load-balancer`。 + +``` +juju add-relation nrpe kubernetes-master +juju add-relation nrpe kubernetes-worker +juju add-relation nrpe etcd +juju add-relation nrpe easyrsa +juju add-relation nrpe kubeapi-load-balancer +``` + + +### 已装 Nagios + + + +如果已经装有 Nagios,可以换用 `nrpe-external-master` charm 。 +这样可以提供配置选项将现有的、外部 Nagios 安装映射到 NRPE上。 +将 `255.255.255.255` 替换为 nagois 实例的 IP 地址。 + +``` +juju deploy nrpe-external-master +juju configure nrpe-external-master nagios_master=255.255.255.255 +``` + + + +配置完后,如上所示,连到 nrpe-external-master。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/networking.md b/content/zh/docs/getting-started-guides/ubuntu/networking.md new file mode 100644 index 0000000000000..e713c53cd7b36 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/networking.md @@ -0,0 +1,92 @@ +--- +title: 网络 +content_template: templates/task +--- + + + +{{% capture overview %}} + + + +Kubernetes 支持[容器网络接口](https://github.com/containernetworking/cni)。 +这个网络插件架构允许你使用任何你喜欢的、对 Kubernetes 友好的 SDN。 +目前支持的插件是 Flannel 和 Canal。 + + +本页将展示集群中各个网络部分是如何工作,并且对它们进行相应的配置。 + +{{% /capture %}} +{{% capture prerequisites %}} + + +本页假设你有一个已经通过 Juju 部署、正在运行的集群。 + +{{< note >}} + +注意,如果你是通过 `conjure-up` 或者 CDK 软件包部署的集群,将不需要再手动部署 CNI 插件。 + +{{< /note >}} +{{% /capture %}} + + +{{% capture steps %}} + + + +CNI charms 在[子路径](https://jujucharms.com/docs/stable/authors-subordinate-applications)下。 +这些 charms 需要主 charm 实现 `kubernetes-cni` 接口,才能正常部署。 + +## Flannel + +``` +juju deploy flannel +juju add-relation flannel kubernetes-master +juju add-relation flannel kubernetes-worker +juju add-relation flannel etcd +``` + +## Canal + +``` +juju deploy canal +juju add-relation canal kubernetes-master +juju add-relation canal kubernetes-worker +juju add-relation canal etcd +``` + + +### 配置 + + + +**iface** 接口是用来配置 flannel 或 canal 的 SDN 绑定。 +如果属性为空字符串或未定义,程序将通过下面的命令行试图找出默认的网络适配器: + +```bash +$ route | grep default | head -n 1 | awk {'print $8'} +``` + + + +**cidr** 在用 etcd 进行网络设置时,用于配置 flannel 或 canal SDN 所要使用的网络地址范围。 +请确保这个网络地址范围在所要部署的 L2/L3 上不是在用状态, +因为如果没有选择一个好的 CIDR 范围来分配给 flannel,就会出现冲突或异常行为。 +同时也要保证 IP 地址范围足够大以支持未来可能会发生的集群扩容。 +A 类 IP 地址 `/24` 是一个不错的选择。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/operational-considerations.md b/content/zh/docs/getting-started-guides/ubuntu/operational-considerations.md new file mode 100644 index 0000000000000..d738f09288eec --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/operational-considerations.md @@ -0,0 +1,262 @@ +--- +title: 运维注意事项 +content_template: templates/task +--- + + + +{{% capture overview %}} + + +本文为管理维护长期运行的集群的工程师提供一些建议和提示。 + +{{% /capture %}} +{{% capture prerequisites %}} + + +本文假定您对 Juju 和 Kubernetes 已经有了基本的了解。 + +{{% /capture %}} + +{{% capture steps %}} + + + +## 管理 Juju + + + +### 确定控制节点规模 + + + +Juju 控制器: + + + +* 运行需要大概 2 到 2.5 GB 的 RAM。 +* 用 MongoDB 数据库作为集群配置和状态的存储后端。这个数据库可能增长很快,也可能是实例中 CPU 周期的最大消费者。 +* 汇总和存储所有服务和单位的日志数据。因此,长期运行的模型需要大量的存储。如果您的目的是保持集群运行,请确保为日志配置至少 64 GB 的存储空间。 + + + +指定参数创建一个控制器(命令行如下): + +``` +juju bootstrap --constraints "mem=8GB cpu-cores=4 root-disk=128G" +``` + + + +Juju 将会选择与目标云上的约束匹配的最便宜的实例类型。 +还可以通过将 ```instance-type``` 与 ```root-disk``` 两个约束结合使用来进行严格控制。 +对于可用的约束信息,请参阅 [官方文档](https://jujucharms.com/docs/stable/reference-constraints) + + + + +关于日志记录的更多信息,请参阅 [日志章节](/docs/getting-started-guides/ubuntu/logging) + + + +### SSH 到控制节点上 + + + +默认情况下,Juju 将创建一对 SSH 密钥,用于自动化单元之间的连接。 +这对密钥保存在客户端节点的 ```~/.local/share/juju/ssh/``` 路径下。 + + + +部署完后,Juju 控制器是一个 "无声单元", +其充当客户端和已部署应用程序之间的代理。 +尽管如此,SSH 到控制器上还是很有用的。 + + + +首先,你需要了解你的运行环境,特别是如果你运行了几个 Juju 模型和控制器。 + +运行下面的命令行: + +``` +juju list-models --all +$ juju models --all +Controller: k8s + +Model Cloud/Region Status Machines Cores Access Last connection +admin/controller lxd/localhost available 1 - admin just now +admin/default lxd/localhost available 0 - admin 2017-01-23 +admin/whale* lxd/localhost available 6 - admin 3 minutes ago +``` + + + +第一行的 ```Controller: k8s``` 表明是如何引导创建的控制器。 + + + +接着可以看见下面列了 2 个,3 个或更多的类型。 + + + +* admin/controller 是托管 juju 所有控制器单元的默认模型 +* admin/default 默认情况下,作为托管用户应用程序的主要模型,例如 Kubernetes 集群 +* admin/whale 是一个额外的模型,如在 Juju 之上,叠加使用 conjure-up 的话 + + + +现在开始 ssh 到控制节点上,首先是让 Juju 切换上下文,然后是像一般单元那样 ssh 到控制节点上: + +``` +juju switch controller +``` + + + +在这个阶段,也可以查询控制器模型: + +``` +juju status +Model Controller Cloud/Region Version +controller k8s lxd/localhost 2.0.2 + +App Version Status Scale Charm Store Rev OS Notes + +Unit Workload Agent Machine Public address Ports Message + +Machine State DNS Inst id Series AZ +0 started 10.191.22.15 juju-2a5ed8-0 xenial +``` + + + +请注意,如果是在 HA 模式下进行的引导, +会在列表中看到几台机器。 + + + +现在 ssh 到控制器节点上,遵循和经典 Juju 命令相同的语义: + +``` +$ juju ssh 0 +Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.8.0-34-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud + +0 packages can be updated. +0 updates are security updates. + + +Last login: Tue Jan 24 16:38:13 2017 from 10.191.22.1 +ubuntu@juju-2a5ed8-0:~$ +``` + + + +在结束完操作,想要返回到最初的模型,退出控制器即可。 + + + +如果,还想要切换回集群,ssh 到其他单元上,运行下面的命令行进行切换: + +``` +juju switch default +``` + + + +## 管理 Kubernetes 集群 + + + +### 运行特权容器 + + + +默认情况下,juju 部署的集群不支持在带有 GPU 的节点上运行特权容器。 +如果需要在其它节点上运行特权容器,只能是在 kubernetes-master 和 kubernetes-worker 节点上 +使能 ```allow-privileged``` 参数: + +``` +juju config kubernetes-master allow-privileged=true +juju config kubernetes-worker allow-privileged=true +``` + + + +### 私有仓库 + + + +通过 registry 操作,您可以很容易地创建一个使用 TLS 身份验证的私有 docker 仓库。 +但是请注意,通过这些功能部署的仓库不是高可用性的; +它使用的存储绑定到运行 pod 的 kubernetes 节点上。 +因此,如果仓库所在的 pod 从一个节点迁移到另一个节点上, +那么你需要重新发布镜像。 + + + +#### 使用示例 + + + +创建相关的身份验证文件。 +例如用户为 ```userA``` 密码为 ```passwordA``` 用来进行身份验证, +命令行如下: + +``` +echo "userA:passwordA" > htpasswd-plain +htpasswd -c -b -B htpasswd userA passwordA +``` + + + +(`htpasswd` 程序通过 ```apache2-utils``` 包获得) + + + +假设您的仓库可以通过 ```myregistry.company.com``` 访问, +您已经在 ```registry.key``` 文件中拥有了您的 TLS 密钥, +并且您的 TLS 身份验证(以 ```myregistry.company.com``` 作为 Common Name)在 +```registry.crt``` 文件中,那么您可以运行: + +``` +juju run-action kubernetes-worker/0 registry domain=myregistry.company.com htpasswd="$(base64 -w0 htpasswd)" htpasswd-plain="$(base64 -w0 htpasswd-plain)" tlscert="$(base64 -w0 registry.crt)" tlskey="$(base64 -w0 registry.key)" ingress=true +``` + + + +如果决定删除镜像仓库,命令行如下: + +``` +juju run-action kubernetes-worker/0 registry delete=true ingress=true +``` + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/rancher.md b/content/zh/docs/getting-started-guides/ubuntu/rancher.md new file mode 100644 index 0000000000000..095b4c92feabb --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/rancher.md @@ -0,0 +1,543 @@ +--- +title: Rancher 与 Ubuntu Kubernetes 集成 +cn-approvers: +- chentao1596 +--- + + + +{{% capture overview %}} + + + +本文将介绍如何在 Canonical Kubernetes 集群上部署 Rancher 2.0 alpha。 + + +这些步骤目前处于 alpha/testing 阶段,未来很可能会发生变化。 + + + +有关此集成的原始文档可以在 [https://github.com/CalvinHartwell/canonical-kubernetes-rancher/](https://github.com/CalvinHartwell/canonical-kubernetes-rancher/) 上找到。 + + +{{% /capture %}} +{{% capture prerequisites %}} + + +本文假设你有一个已经通过 Juju 部署、正在运行的集群。 + + + +有关使用 juju 部署 Kubernetes 集群的完整指导,请参考 [/docs/getting-started-guides/ubuntu/installation/](/docs/getting-started-guides/ubuntu/installation/)。 + +{{% /capture %}} + + +{{% capture steps %}} + + +## 部署 Rancher + + + +想要部署 Rancher,我们只需要在 Kubernetes 集群上运行 Rancher 容器工作负载即可。 +Rancher 通过 dockerhub([https://hub.docker.com/r/rancher/server/tags/](https://hub.docker.com/r/rancher/server/tags/)) +提供他们的容器镜像的免费下载。 + + + +如果您正在使用自己的镜像仓库,或进行离线部署, +那么,在开始部署之前,请先下载好这些容器镜像,将其推入私有镜像仓库中。 + + +### 使用 nodeport 部署 Rancher + + +首先创建一个 yaml 文件,该文件定义了如何在 kubernetes 上部署 Rancher。 +将该文件保存为 cdk-rancher-nodeport.yaml: + +``` +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-admin +subjects: + - kind: ServiceAccount + name: default + namespace: default +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-admin +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: rancher + name: rancher +spec: + replicas: 1 + selector: + matchLabels: + app: rancher + ima: pod + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: rancher + ima: pod + spec: + containers: + - image: rancher/server:preview + imagePullPolicy: Always + name: rancher + ports: + - containerPort: 80 + - containerPort: 443 + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + timeoutSeconds: 30 + resources: {} + restartPolicy: Always + serviceAccountName: "" +status: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: rancher + labels: + app: rancher +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 443 + selector: + app: rancher +--- +apiVersion: v1 +kind: Service +metadata: + name: rancher-nodeport +spec: + type: NodePort + selector: + app: rancher + ports: + - name: rancher-api + protocol: TCP + nodePort: 30443 + port: 443 + targetPort: 443 +``` + + + +kubectl 开始正常运行后,执行下面的命令开始部署 Rancher: + +``` + kubectl apply -f cdk-rancher-nodeport.yaml +``` + + + +现在我们需要打开这个 nodeport,以供访问。 +为此,我们可以使用 juju。我们需要在集群中的每个工作节点上运行 open-port 命令。 +在 cdk-rancher-nodeport.yaml 文件中,nodeport 已设置为 30443。 +下面的命令行展示如何在每个工作节点上打开端口: + + + +``` + # 在集群的每个工作节点上运行下面的命令行 + juju run --unit kubernetes-worker/0 "open-port 30443" + juju run --unit kubernetes-worker/1 "open-port 30443" + juju run --unit kubernetes-worker/2 "open-port 30443" +``` + + + +现在便可以通过工作节点的 IP 或 DNS 记录(如果已经创建)在此端口上访问 Rancher。 +通常建议您为集群中的每个工作节点创建一条 DNS 记录。 +例如,如果有三个工作节点并且域名是 example.com,则可以创建三条 A 记录,集群中的每个工作节点各一条。 + + + +由于创建 DNS 记录超出了本文关注的范围, +我们将使用免费服务 xip.io 来获得和 IP 地址相对应的 A 记录,IP 地址将是域名的一部分。 +例如,如果有域名 rancher.35.178.130.245.xip.io, +则 xip.io 服务会自动将 IP 地址 35.178.130.245 作为 A 记录返回,这对测试相当有用。 +至于您的部署,IP 地址 35.178.130.245 应该替换为集群工作节点的 IP 地址,这个 IP 地址可以通过 Juju 或 AWS 得到: + + + +``` + calvinh@ubuntu-ws:~/Source/cdk-rancher$ juju status + +# ... 输出省略。 + +Unit Workload Agent Machine Public address Ports Message +easyrsa/0* active idle 0 35.178.118.232 Certificate Authority connected. +etcd/0* active idle 1 35.178.49.31 2379/tcp Healthy with 3 known peers +etcd/1 active idle 2 35.177.99.171 2379/tcp Healthy with 3 known peers +etcd/2 active idle 3 35.178.125.161 2379/tcp Healthy with 3 known peers +kubeapi-load-balancer/0* active idle 4 35.178.37.87 443/tcp Loadbalancer ready. +kubernetes-master/0* active idle 5 35.177.239.237 6443/tcp Kubernetes master running. + flannel/0* active idle 35.177.239.237 Flannel subnet 10.1.27.1/24 +kubernetes-worker/0* active idle 6 35.178.130.245 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/2 active idle 35.178.130.245 Flannel subnet 10.1.82.1/24 +kubernetes-worker/1 active idle 7 35.178.121.29 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/3 active idle 35.178.121.29 Flannel subnet 10.1.66.1/24 +kubernetes-worker/2 active idle 8 35.177.144.76 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/1 active idle 35.177.144.76 + +# 注意上面输出中 kubernetes-worker 的 IP 地址,可以选一个用作设置。 +``` + + + +尝试使用 nodeport 搭配域名或 IP 地址在浏览器中打开 Rancher: + + + +``` + # 将 IP 地址替换为某个 Kubernetes 工作节点的公共地址,通过 juju status 命令进行查找。 + wget https://35.178.130.245.xip.io:30443 --no-check-certificate + + # 这条命令也应该能工作 + wget https://35.178.130.245:30443 --no-check-certificate +``` + + + +如果需要对 kubernetes 配置文件进行任何更改,编辑 yaml 文件,再重新 apply 即可: + +``` + kubectl apply -f cdk-rancher-nodeport.yaml +``` + + +### 使用 ingress 规则部署 Rancher + + + +也可以使用 ingress 规则来部署 Rancher。 +这还有另外一个好处,就是不需要在 Kubernetes 集群上打开额外的端口。 +首先创建一个名为 cdk-rancher-ingress.yaml 的文件,内容如下: + +``` +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-admin +subjects: + - kind: ServiceAccount + name: default + namespace: default +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-admin +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: rancher + name: rancher +spec: + replicas: 1 + selector: + matchLabels: + app: rancher + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: rancher + spec: + containers: + - image: rancher/server:preview + imagePullPolicy: Always + name: rancher + ports: + - containerPort: 443 + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + timeoutSeconds: 30 + resources: {} + restartPolicy: Always + serviceAccountName: "" +status: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: rancher + labels: + app: rancher +spec: + ports: + - port: 443 + targetPort: 443 + protocol: TCP + selector: + app: rancher +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: rancher + annotations: + kubernetes.io/tls-acme: "true" + ingress.kubernetes.io/secure-backends: "true" +spec: + tls: + - hosts: + - rancher.34.244.118.135.xip.io + rules: + - host: rancher.34.244.118.135.xip.io + http: + paths: + - path: / + backend: + serviceName: rancher + servicePort: 443 +``` + + + +通常建议您为集群中的每个工作节点创建一条 DNS 记录。 +例如,如果有三个工作节点并且域名是 example.com,则可以创建三条 A 记录,集群中的每个工作节点各一条。 + + + +由于创建 DNS 记录超出了本文关注的范围, +我们将使用免费服务 xip.io 来获得和 IP 地址相对应的 A 记录,IP 地址将是域名的一部分。 +例如,如果有域名 rancher.35.178.130.245.xip.io, +则 xip.io 服务会自动将 IP 地址 35.178.130.245 作为 A 记录返回,这对测试相当有用。 + + + +至于您的部署,IP 地址 35.178.130.245 应该替换为集群工作节点的 IP 地址,这个 IP 地址可以通过 Juju 或 AWS 得到: + + + +``` + calvinh@ubuntu-ws:~/Source/cdk-rancher$ juju status + +# ... 输出省略。 + +Unit Workload Agent Machine Public address Ports Message +easyrsa/0* active idle 0 35.178.118.232 Certificate Authority connected. +etcd/0* active idle 1 35.178.49.31 2379/tcp Healthy with 3 known peers +etcd/1 active idle 2 35.177.99.171 2379/tcp Healthy with 3 known peers +etcd/2 active idle 3 35.178.125.161 2379/tcp Healthy with 3 known peers +kubeapi-load-balancer/0* active idle 4 35.178.37.87 443/tcp Loadbalancer ready. +kubernetes-master/0* active idle 5 35.177.239.237 6443/tcp Kubernetes master running. + flannel/0* active idle 35.177.239.237 Flannel subnet 10.1.27.1/24 +kubernetes-worker/0* active idle 6 35.178.130.245 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/2 active idle 35.178.130.245 Flannel subnet 10.1.82.1/24 +kubernetes-worker/1 active idle 7 35.178.121.29 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/3 active idle 35.178.121.29 Flannel subnet 10.1.66.1/24 +kubernetes-worker/2 active idle 8 35.177.144.76 80/tcp,443/tcp,30443/tcp Kubernetes worker running. + flannel/1 active idle 35.177.144.76 + +# 注意上面输出中 kubernetes-worker 的 IP 地址,可以选一个用作设置。 +``` + + + +查看上面 juju status 的命令输出,可以拿公共地址(35.178.130.245)来创建 xip.io DNS记录(rancher.35.178.130.245.xip.io),记录可以加到 cdk-rancher-ingress.yaml 文件中。 +你也同样可以创建自己的 DNS 记录,只要能解析到集群上的工作节点即可: + + + +``` + # xip.io 在文件中会出现两次,请都替换修改。 + cat cdk-rancher-ingress.yaml | grep xip.io + - host: rancher.35.178.130.245.xip.io +``` + + + +修改完 ingress 规则之后,可以运行 `kubectl apply -f cdk-rancher-ingress.yaml` 命令来更新 Kubernetes 集群: + +``` + kubectl apply -f cdk-rancher-ingress.yaml +``` + + + +现在可以通过工作节点 IP 或者 DNS 记录(如果已创建)在常规的 443 上访问 Rancher。 +尝试在浏览器中打开它: + + + +``` + # 将 IP 地址替换为某个 Kubernetes 工作节点的公共地址,通过 juju status 命令进行查找。 + wget https://35.178.130.245.xip.io:443 --no-check-certificate +``` + + + +如果需要对 kubernetes 配置文件进行任何更改,请编辑 yaml 文件,再 apply: + +``` + kubectl apply -f cdk-rancher-ingress.yaml +``` + + +### 删除 Rancher + + + +您可以使用 kubectl 从集群中删除 Rancher。 +在 Kubernetes 中删除对象与创建它们的过程一样简单: + + + +``` + # 使用 nodeport 示例(如果使用 ingress 示例,请修改文件名) + kubectl delete -f cdk-rancher-nodeport.yaml +``` + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/scaling.md b/content/zh/docs/getting-started-guides/ubuntu/scaling.md new file mode 100644 index 0000000000000..a24c136eeb430 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/scaling.md @@ -0,0 +1,147 @@ +--- +title: 扩缩 +content_template: templates/task +--- + + + +{{% capture overview %}} + + +本文将讨论如何在集群中扩缩主节点和工作节点。 + +{{% /capture %}} + +{{% capture prerequisites %}} + + + +本文假设您已经有一个用 Juju 部署、正在运行的集群。 + + + +任何应用都可以在部署之后进行横向扩容。 +charms 将会不停地更新进度状态信息,建议运行如下命令。 + +``` +watch -c juju status --color +``` +{{% /capture %}} + +{{% capture steps %}} + + + +## Kubernetes 主节点 + + + +Kubernetes 主节点充当了集群中控制平面的角色。 +在设计上,这些主节点可以独立于工作节点进行扩缩容,从而带来运维上的灵活性。 +想要添加一个主节点,只需要执行以下命令: + + juju add-unit kubernetes-master + + + +这将会在控制平面中添加一个新的主节点。 +参见[构建高可用集群](/docs/admin/high-availability)文档,获取更多信息。 + + + +## Kubernetes 工作节点 + + + +kubernetes-worker 节点是 Kubernetes 集群中承担负载的部分。 + + + +默认情况下,pod 会自动均匀部署在 kubernetes-worker 节点上。 + + + +如果想要在集群中添加更多的 kubernetes-worker 节点,运行如下命令: + +``` +juju add-unit kubernetes-worker +``` + + + +或者修改机器限制,来创建更大的节点: + +``` +juju set-constraints kubernetes-worker "cpu-cores=8 mem=32G" +juju add-unit kubernetes-worker +``` + + + +参见[机器限制文档](https://jujucharms.com/docs/stable/charms-constraints), +了解其它机器约束,这些约束可能对 kubernetes-worker unit 有帮助。 + +## etcd + + + +Etcd 在 Kubernetes 集群中用作键值存储。 +集群默认使用一个存储实例。 + + + +由于仲裁机制的关系,推荐保有奇数个 etcd 节点。 +根据集群的大小,推荐使用3、5、7 或 9 个节点。 +CoreOS etcd 文档有一个关于[最佳集群大小](https://coreos.com/etcd/docs/latest/admin_guide.html#optimal-cluster-size)的图表, +可以参考确定最佳的容错设计。 + + +添加 etcd 单元: + +``` +juju add-unit etcd +``` + + +不建议在扩容 etcd 集群之后对其缩容。 + + +## Juju 控制器 + + + +一个负责协调每台机器上 Juju 代理(这些代理管理 Kubernetes 集群)的节点被称为控制器节点。 +对于生产环境下的部署,建议启用控制器节点的高可用性: + + juju enable-ha + + + +启用 HA 将会创建 3 个控制器节点,对于大多数情况而言应该是足够的。 +而对于超大型的部署,也同时支持 5 或 7 个控制器节点。 + + + +参见 [Juju HA 控制器文档](https://jujucharms.com/docs/2.2/controllers-ha) 获取更多信息. + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/storage.md b/content/zh/docs/getting-started-guides/ubuntu/storage.md new file mode 100644 index 0000000000000..04aa262d9b3e1 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/storage.md @@ -0,0 +1,138 @@ +--- +title: 存储 +content_template: templates/task +--- + + + +{{% capture overview %}} + + +本文解释了如何在集群中安装和配置持久化存储。 + +{{% /capture %}} + +{{% capture prerequisites %}} + + +本文假设您已经有一个用 Juju 部署、正在运行的集群。 + +{{% /capture %}} + +{{% capture steps %}} + + +## Ceph 持久卷 + + + +Canonical 的 Kubernetes 发行版允许添加持久化存储设备,例如 [Ceph](http://ceph.com)。 +配合 [Juju Storage](https://jujucharms.com/docs/2.0/charms-storage)功能, +可以跨云平台,添加持久化存储。 + + + +部署一个至少有三个 ceph-mon 和三个 ceph-osd 单元的存储池。 + +``` +juju deploy cs:ceph-mon -n 3 +juju deploy cs:ceph-osd -n 3 +``` + + +关联这些单元: + +``` +juju add-relation ceph-mon ceph-osd +``` + + +列出云上 Juju 可用的存储池: + + juju storage-pools + + +输出: + +``` +Name Provider Attrs +ebs ebs +ebs-ssd ebs volume-type=ssd +loop loop +rootfs rootfs +tmpfs tmpfs +``` + +{{< note >}} + + + +注意列表使用的是 AWS,不同的云有不同的存储池名称。 + +{{< /note >}} + + + +以 “名字,大小,数量”的格式往 ceph-osd charm 中添加存储池: + +``` +juju add-storage ceph-osd/0 osd-devices=ebs,10G,1 +juju add-storage ceph-osd/1 osd-devices=ebs,10G,1 +juju add-storage ceph-osd/2 osd-devices=ebs,10G,1 +``` + + +接下来将 Kubernetes 和存储集群相关联: + +``` +juju add-relation kubernetes-master ceph-mon +``` + + + + +现在我们可以在 Kubernetes 中列举可用的[持久卷](/docs/concepts/storage/persistent-volumes/), +集群中的负载可以通过 PVC 申领来使用这些持久卷。 + +``` +juju run-action kubernetes-master/0 create-rbd-pv name=test size=50 +``` + + + +本例中创建了 50 MB 大小的 “test” Rados 块设备 (rbd)。 + +在 Kubernetes 集群上使用如下所示的 watch 命令,可以看到 PV 加入列表,并被标记可用的过程: + + watch kubectl get pv + + +输出: + +``` +NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE + +test 50M RWO Available 10s +``` + + + +要使用这些持久卷,pods 需要关联一个持久卷申领,这超出了本文档的讨论范围。 +参见[持久卷](/docs/concepts/storage/persistent-volumes/)获取更多信息。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/troubleshooting.md b/content/zh/docs/getting-started-guides/ubuntu/troubleshooting.md new file mode 100644 index 0000000000000..be76e9eb9182e --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/troubleshooting.md @@ -0,0 +1,272 @@ +--- +title: 故障排除 +--- + + + +{{% capture overview %}} + + + +本文重点讨论如何解决 Kubernetes 集群部署过程中的问题, +而不会关心如何调试 Kubernetes 集群内的工作负载。 + +{{% /capture %}} + +{{% capture prerequisites %}} + + + +本文假设您已经有一个用 Juju 部署、正在工作的集群。 + +{{% /capture %}} + +{{% capture steps %}} + + +## 了解集群状态 + + +使用 `juju status` 命令可以了解一些集群内的情况: + +``` +Model Controller Cloud/Region Version +kubes work-multi aws/us-east-2 2.0.2.1 + +App Version Status Scale Charm Store Rev OS Notes +easyrsa 3.0.1 active 1 easyrsa jujucharms 3 ubuntu +etcd 2.2.5 active 1 etcd jujucharms 17 ubuntu +flannel 0.6.1 active 2 flannel jujucharms 6 ubuntu +kubernetes-master 1.4.5 active 1 kubernetes-master jujucharms 8 ubuntu exposed +kubernetes-worker 1.4.5 active 1 kubernetes-worker jujucharms 11 ubuntu exposed + +Unit Workload Agent Machine Public address Ports Message +easyrsa/0* active idle 0/lxd/0 10.0.0.55 Certificate Authority connected. +etcd/0* active idle 0 52.15.47.228 2379/tcp Healthy with 1 known peers. +kubernetes-master/0* active idle 0 52.15.47.228 6443/tcp Kubernetes master services ready. + flannel/1 active idle 52.15.47.228 Flannel subnet 10.1.75.1/24 +kubernetes-worker/0* active idle 1 52.15.177.233 80/tcp,443/tcp Kubernetes worker running. + flannel/0* active idle 52.15.177.233 Flannel subnet 10.1.63.1/24 + +Machine State DNS Inst id Series AZ +0 started 52.15.47.228 i-0bb211a18be691473 xenial us-east-2a +0/lxd/0 started 10.0.0.55 juju-153b74-0-lxd-0 xenial +1 started 52.15.177.233 i-0502d7de733be31bb xenial us-east-2b +``` + + + +在这个例子中,我们可以获取一些信息。 `Workload` 列将显示给定服务的状态。 +`Message` 部分将显示集群中给定服务的健康状况。 在部署和维护期间, +这些工作负载状态将进行更新以反映给定节点正在执行的操作。例如, +Workload 可能显示为 `maintenance`,而 Message 则会相应显示为 `Installing docker`。 + + + +正常情况下,Workload 列应该为 `active`,Agent 列(用于反映 Juju 代理正在做什么)应该为 `idle`, +而 Message 要么是 `Ready` 或者其它描述性的术语。 +如果集群运行健康,`juju status --color` 返回的结果输出都将是绿色的。 + + + +对于大型集群而言,状态信息可能会太多,因此建议检查各个服务的状态,例如仅检查工作节点的状态: + + juju status kubernetes-worker + + +或者只检查 etcd 集群的状态: + + juju status etcd + +Errors will have an obvious message, and will return a red result when used with +`juju status --color`. Nodes that come up in this manner should be investigated. + +错误都会有明显的错误信息,使用 `juju status --color` 的返回结果也将是红色的。 +如果节点状态出现这种情况,需要相应地检查了解。 + + +## SSH 到各个单元上 + + + +按照 `juju ssh <服务名>/<单元#>` 的命令格式可以轻松地连接到各个单元上: + + juju ssh kubernetes-worker/3 + + +将会 ssh 到第 3 个工作单元上。 + + juju ssh easyrsa/0 + + +将会 ssh 到第 0 个 easyrsa 单元上。 + + +## 收集调试信息 + + + +有时候,从集群上收集所有的信息,并与开发人员共享,将有助于发现问题。 +这最好是通过 [CDK Field Agent](https://github.com/juju-solutions/cdk-field-agent) 来完成。 + + + +在带有 Juju 客户端,而客户端配有指向相应的 CDK 部署的控制器的节点上, +下载并执行[CDK Field Agent](https://github.com/juju-solutions/cdk-field-agent)中的 collect.py 文件。 + + + +运行该脚本会生成一个 tar 包,包含系统信息以及诸如 systemctl 状态,Juju 日志,charm 单元数据等基本信息。 +额外和应用相关的信息可能也会包含其中。 + + + +## 常见问题 + + + +### 负载均衡器对 Helm 的影响 + + + +本节假定有一个用 Juju 部署的正在运行的 Kubernetes 集群,使用负载均衡器来代理 API,同时也用 Helm 来进行 chart 部署。 + + +Helm 初始化: + +``` +helm init +$HELM_HOME has been configured at /home/ubuntu/.helm +Tiller (the helm server side component) has been installed into your Kubernetes Cluster. +Happy Helming! +``` + + +随后使用 helm 时,可能会出现以下错误: + + +* Helm 不能从 Tiller 服务器获取版本号 + +``` +helm version +Client: &version.Version{SemVer:"v2.1.3", GitCommit:"5cbc48fb305ca4bf68c26eb8d2a7eb363227e973", GitTreeState:"clean"} +Error: cannot connect to Tiller +``` + + +* Helm 不能安装 chart + +``` +helm install --debug +Error: forwarding ports: error upgrading connection: Upgrade request required +``` + + + +这是因为 API 负载均衡器在 helm 客户端-服务端关系的上下文中不进行端口转发造成的。 +要使用 helm 进行部署,需要执行以下步骤: + + +1. 暴露 Kubernetes Master 服务 + + ``` + juju expose kubernetes-master + ``` + + +1. 确定其中一个主节点的公开 IP 地址 + + ``` + juju status kubernetes-master + Model Controller Cloud/Region Version + production k8s-admin aws/us-east-1 2.0.0 + + App Version Status Scale Charm Store Rev OS Notes + flannel 0.6.1 active 1 flannel jujucharms 7 ubuntu + kubernetes-master 1.5.1 active 1 kubernetes-master jujucharms 10 ubuntu exposed + + Unit Workload Agent Machine Public address Ports Message + kubernetes-master/0* active idle 5 54.210.100.102 6443/tcp Kubernetes master running. + flannel/0 active idle 54.210.100.102 Flannel subnet 10.1.50.1/24 + + Machine State DNS Inst id Series AZ + 5 started 54.210.100.102 i-002b7150639eb183b xenial us-east-1a + + Relation Provides Consumes Type + certificates easyrsa kubernetes-master regular + etcd etcd flannel regular + etcd etcd kubernetes-master regular + cni flannel kubernetes-master regular + loadbalancer kubeapi-load-balancer kubernetes-master regular + cni kubernetes-master flannel subordinate + cluster-dns kubernetes-master kubernetes-worker regular + cni kubernetes-worker flannel subordinate + ``` + + + + 本例中,公开 IP 地址为 54.210.100.102。 + 如果想编程访问得到这个值,可以使用 JSON 输出: + + ``` + juju show-status kubernetes-master --format json | jq --raw-output '.applications."kubernetes-master".units | keys[]' + 54.210.100.102 + ``` + + +1. 更新 kubeconfig 文件 + + + + 确定集群所使用的 kubeconfig 文件或配置部分,然后修改服务器配置。 + + 默认情况下,这个配置类似于 ```https://54.213.123.123:443```。将其替换为 Kubernetes Master 端点地址 + ```https://54.210.100.102:6443``` 并保存。 + + 注意,Kubernetes Master API 的 CDK 默认使用的端口为 6443,而负载均衡器暴露的端口是 443。 + + +1. 继续使用 helm! + + ``` + helm install --debug + Created tunnel using local port: '36749' + SERVER: "localhost:36749" + CHART PATH: /home/ubuntu/.helm/ + NAME: + ... + ... + ``` + + +## 日志和监控 + + + +默认情况下, Kubernetes 没有节点的日志聚合,每个节点都是本地保存日志。 +请参阅[日志](/docs/getting-started-guides/ubuntu/logging/)文档,获取更多信息。 + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/ubuntu/upgrades.md b/content/zh/docs/getting-started-guides/ubuntu/upgrades.md new file mode 100644 index 0000000000000..9df7fb310a639 --- /dev/null +++ b/content/zh/docs/getting-started-guides/ubuntu/upgrades.md @@ -0,0 +1,273 @@ +--- +title: 升级 +content_template: templates/task +--- + + + +{{% capture overview %}} + +本页将展示如何进行 Kubernetes 集群升级。 +{{% /capture %}} + +{{% capture prerequisites %}} + +本页假定你有一个 juju 部署的集群。 + +{{< warning >}} + + + +在进行升级之前,你应当备份所有的数据。 +不要忘记对集群内的工作负载进行数据备份! +参见[备份文档](/docs/getting-started-guides/ubuntu/backups)。 + +{{< /warning >}} + +{{% /capture %}} + +{{% capture steps %}} + + +## 对集群进行补丁版本升级,例如,1.9.0 -> 1.9.1 + + + +集群透明地升级到最新的 Kubernetes 补丁版本。 +需要澄清的是,用 1.9/stable 通道部署的集群将会透明地、自动更新到 Kubernetes 1.9.X 最新版。 +升级的过程对集群的运行没有影响,也不需要集群维护人员的干预。 +每一个补丁版本都由 Canonical Kubernetes 发布小组审核评估。 +一旦补丁版本通过了内部测试,认为可以安全用于集群升级, +将会被打包成 snap 格式,发布到稳定版通道上。 + + +## 对集群进行次版本升级,例如,1.8.1 -> 1.9.0 + + + +Kubernetes charms 遵循的是 Kubernetes 发行版本。 +请咨询了解 support 计划在升级频率方面的相关信息。 +重要的运维考虑以及行为上的改变都会记录在发布通知里。 + + +### 升级 etcd + + + +备份 etcd 需要导出和快照操作,参见[备份文档](/docs/getting-started-guides/ubuntu/backups)了解如何创建快照。 +在做完快照后,用下面的命令升级 etcd 服务: + + juju upgrade-charm etcd + + + +命令将会负责 etcd 的次版本升级。 +在 [juju 解决方案的 wiki](https://github.com/juju-solutions/bundle-canonical-kubernetes/wiki/Etcd-2.3-to-3.x-upgrade) 里 +可以了解如何将 etcd 从 2.x 升级到 3.x。 + + +### 升级 kubeapi-load-balancer + + + +Kubernetes Charms 通常是同时更新、发布。 +Ubuntu 集群的核心部分是 kubeapi-load-balancer 组件。 +错误或遗失修改可能会导致 API 可用性和访问控制方面的问题。 +为了保证 API 服务在集群升级期间还能为主节点和工作节点服务,也需要对它们进行升级。 + + + +升级命令: + + juju upgrade-charm kubeapi-load-balancer + + +### 升级 Kubernetes + + + +Kubernetes Charms 使用 snap 通道来驱动负荷。 +这些通道定义的格式为 `X.Y/channel`,其中,`X.Y` 是 Kubernetes `主.次` 发行版(例如,1.9) +而 `channel` 的取值范围如下: + + + +| 通道名 | 描述 | +| ------------------- | ------------ | +| stable | Kubernetes 的最新稳定发行版 | +| candidate | Kubernetes 的发行候选版 | +| beta | Kubernetes 次发行版的最新 alpha 或 beta 版 | +| edge | Kubernetes 次发行版的每日构建版 | + + + + +如果发行版还不可用,就会使用下一个最高通道的版本。 +例如,1.9/beta 会根据发行版的可用性加载 `/candidate` 或 `/stable` 版本。 +Kubernetes 的开发版本会根据每个次版本,发布到 edge 通道上。 +但不会保证 edge snap 能够和当前的 charms 一起工作。 + + +### 主节点升级 + + + +首先需要对主节点进行升级: + + juju upgrade-charm kubernetes-master + +{{< note >}} + + + +永远在工作节点升级之前,升级主节点。 + +{{< /note >}} + + + +在部署完最新的 charm 之后,可以通过下面的命令行来选择通道: + + juju config kubernetes-master channel=1.x/stable + + + +其中,`x` 是 Kubernetes 的次版本号。例如,`1.9/stable`。 +参阅前面对通道的定义。 +将 kubernetes-master 配置到合适的通道上后, +再在每个主节点上运行下面的升级命令: + + juju run-action kubernetes-master/0 upgrade + juju run-action kubernetes-master/1 upgrade + ... + + +### 工作节点升级 + + + +现有所支持的升级工作节点的方法有两种,[蓝/绿部署](http://martinfowler.com/bliki/BlueGreenDeployment.html) +和就地升级。提供两种方法可以带来运维上的灵活性,而这两种方法也都被支持和测试。 +相比于就地升级,蓝/绿部署需要更多的硬件资源,但也更为安全可靠。 + + +#### 蓝/绿工作节点升级 + + + +假定一个部署里面所有的工作节点都叫 kubernetes-alpha。 + + + +部署新的工作节点: + + juju deploy kubernetes-alpha + + + +暂停旧的工作节点,然后迁移工作负载: + + juju run-action kubernetes-alpha/# pause + + + +验证所迁移的工作负载: + + kubectl get pod -o wide + + + +销毁就有的工作节点: + + juju remove-application kubernetes-alpha + + +#### 就地工作节点升级 + + juju upgrade-charm kubernetes-worker + juju config kubernetes-worker channel=1.x/stable + + + +其中,`x` 是 Kubernetes 的次版本号。例如,`1.9/stable`。 +参阅前面对通道的定义。将 kubernetes-worker 配置到合适的通道上后, +再在每个工作节点上运行下面的升级命令: + + juju run-action kubernetes-worker/0 upgrade + juju run-action kubernetes-worker/1 upgrade + ... + + +### 验证升级 + + + +`kubectl version` 将会返回新的版本号。 + + + +建议重新运行[集群验证](/docs/getting-started-guides/ubuntu/validation)确认集群升级成功完成。 + + +### 升级 Flannel + + + +可以在任何时候升级 flannel,它的升级可以和 Kubernetes 升级分开进行。 +需要注意的是,在升级过程中,网络会受到影响。 +可以通过下面的命令行发起升级: + + juju upgrade-charm flannel + + +### 升级 easyrsa + + + +可以在任何时候升级 easyrsa,它的升级可以和 Kubernetes 升级分开进行。 +升级 easyrsa 会有停机时间,因为不是运行服务: + + juju upgrade-charm easyrsa + +{{% /capture %}} diff --git a/content/zh/docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png b/content/zh/docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png new file mode 100644 index 0000000000000..520f6ae9e6c54 Binary files /dev/null and b/content/zh/docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png differ diff --git a/content/zh/docs/getting-started-guides/windows/UpstreamRouting.png b/content/zh/docs/getting-started-guides/windows/UpstreamRouting.png new file mode 100644 index 0000000000000..91189c36af3ba Binary files /dev/null and b/content/zh/docs/getting-started-guides/windows/UpstreamRouting.png differ diff --git a/content/zh/docs/getting-started-guides/windows/_index.md b/content/zh/docs/getting-started-guides/windows/_index.md new file mode 100644 index 0000000000000..343feaafcb3e2 --- /dev/null +++ b/content/zh/docs/getting-started-guides/windows/_index.md @@ -0,0 +1,892 @@ +--- +title: 在 Kubernetes 中使用 Windows Server 容器 +toc_hide: true +--- + + + +{{< note >}} +**Note:** 这些说明最近基于 Windows Server 平台增强和 Kubernetes v1.9 版本进行了更新 +{{< /note >}} + + + +Kubernetes 1.5 版本基于 Windows Server 2016 操作系统引入了对 Windows Server 容器 +的 Alpha 支持。随着 Windows Server 版本 1709 的发布和使用 Kubernetes v1.9,用户可以使用许多不同的 +网络拓扑和 CNI 插件在本地或私有/公共云中部署 Kubernetes 集群。Kubernetes 上的 Windows Server 容器的一些 +关键功能改进包括: + + + +- 改进了对 pod 的支持!具有多个 Windows Server 容器(共享内核)的共享网络命名空间(隔离专区) + + + +- 通过每个 pod 使用单个网络端点降低网络复杂性 + + + +- 使用虚拟过滤平台 (VFP)Hyper-v 交换机扩展(类似于 Linux iptables) 的基于内核的负载均衡 + + + +- 容器运行时接口(CRI) pod 和 节点级统计 + + + +- 支持 kubeadm 命令将 Windows Server 节点添加到 Kubernetes 环境中 + + + +Kubernetes 控制平面(API服务器,调度程序,控制器管理器等)继续在 Linux 上运行,而 kubelet 和 kube-proxy 可以在 Windows Server 2016 或更高版本上运行 + + + +{{< note >}} +**Note:** Kubernetes 上的 Windows Server 容器是 Kubernetes v1.9 中的一个 Beta 特性 +{{< /note >}} + + + +## 获取 Windows 二进制文件 + + + +我们建议使用可以在 [https://github.com/kubernetes/kubernetes/releases/latest](https://github.com/kubernetes/kubernetes/releases/latest) 上找到的发布的二进制文件。在更新日志下您可以找到 Windows-amd64 的节点二进制文件链接,其中包括 kubeadm,kubectl,kubelet 和 kube-proxy。 + + + +如果您希望自己构建代码,请参阅[此处](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries)的详细构建说明。 + + + +## 环境准备 + +在 Kubernetes 1.9 或更高版本中,使用以下内容支持 Kubernetes 的 Windows Server 容器: + + +1. Kubernetes 控制平面在现有的 Linux 基础架构(1.9版本或更高版本)上运行。 + +2. Linux 的节点上的 Kubenet 网络插件设置。 + +3. Windows Server 2016 RTM 或更高版本,Windows Server 版本 1709 或更高版本是首选; 它解锁了共享网络命名空间等关键功能。 + +4. 适用于 Windows Server 节点的 Docker 版本 17.06.1-ee-2 或更高版本(Linux 节点和 Kubernetes 控制平面可以运行任何 Kubernetes 支持的 Docker 版本)。 + + +## 网络 + + + +Windows 上有几种支持 Kubernetes v1.9 的网络配置,包括使用第三方网络插件的第三层路由和覆盖拓扑。 + + +1. [上游 L3 路由](#upstream-l3-routing-topology) - 在上游 ToR 中配置的 IP 路由 + +2. [主机网关](#host-gateway-topology) - 在每台主机上配置的 IP 路由 + +3. [使用覆盖式 Open vSwitch(OVS) 和开放虚拟网络(OVN)](#using-ovn-with-ovs) - 覆盖网络(支持STT和Geneve隧道类型) + +4. [未来 - 评审中] 覆盖 - 使用 Flannel 的 VXLAN 或者 IP-in-IP 封装 + +5. [未来] 使用 BGP(Calico) 的第三层路由 + + +选择要部署的网络配置和拓扑取决于物理网络拓扑和用户配置路由的能力,封装的性能问题以及与第三方网络插件集成的要求。 + + +### 未来的 CNI 插件 +另外两个 CNI 插件 [win-l2bridge(主机网关)和 win-overlay(vxlan)] 正在进行 PR 审核。这两个 CNI 插件准备好后,既可以直接使用,也可以与 Flannel 一起使用。 + + + +### Linux +Linux 上已经使用桥接接口支持上述网络方法,桥接接口基本上创建了节点本地的专用网络。与 Windows 端类似,必须创建到所有其他 pod CIDR 的路由才能通过"公共" NIC 发送数据包。 + + + +### Windows +Windows 支持 CNI 网络模型,并使用插件与 Windows 主机网络服务(HNS)连接以配置主机网络和策略。在撰写本文时,Microsoft 唯一公开提供的 CNI 插件是从私人存储库构建的,可在此处获得[wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe)。它使用由管理员在每个节点上使用 HNS PowerShell 命令通过 Windows 主机网络服务(HNS)创建的 l2bridge 网络,如下面的 [Windows 主机设置](#windows-host-setup)部分所述。未来CNI插件的源代码将公开发布 + + + +#### 上游 L3 路由拓扑 +在这种拓扑结构中,通过在机架 (ToR)交换机/路由器的上游顶部配置静态 IP 路由,使用L3路由实现网络连接。每个群集节点都通过主机 IP 连接到管理网络。此外,每个节点使用本地'l2bridge'网络,并分配了一个 pod CIDR。给定工作节点上的所有 pod 将连接到 pod CIDR 子网('l2bridge'网络)。为了在不同节点上运行的 pod 之间实现网络通信,上游路由器配置了静态路由 pod CIDR 前缀 => 主机 IP。 + + + +以下示例图说明了使用上游 L3 路由设置的 Kubernetes 的 Windows Server 网络设置: + + +![K8s 集群使用 ToR 的 L3 路由](UpstreamRouting.png) + + + +#### 主机网关拓扑 +这种拓扑与上游 L3 路由拓扑相似,惟一的区别是静态 IP 路由是直接在每个集群节点上配置的,而不是在上游 ToR 中配置的。每个节点使用本地的 'l2bridge' 网络,并像以前一样分配 pod CIDR,并为分配给远程集群节点的所有其他 pod CIDR 子网提供路由表条目。 + + + +#### OVN 和 OVS 一起使用 +下图概述了组件之间的体系结构和交互: + + + +![覆盖式使用 OVN 控制器和 OVS 开关扩展](ovn_kubernetes.png) + + + +(上图来自 [https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram](https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram)) + + + +由于它的体系结构,OVN 有一个中央组件,它将您的网络意图存储在数据库中。其他组件如 kube-apiserver、kube-controller-manager、kube-scheduler 等也可以部署在该中心节点上。 + + +## 在 Kubernetes 上设置 Windows Server 容器 +要在 Kubernetes 上运行 Windows Server 容器,您需要为 Windows 设置主机和 Kubernetes 节点组件。根据您的网络拓扑,可能需要为不同节点上的 pod 通信设置路由。 + + + +### 主机设置 + + + +#### 1. 上游 L3 路由拓扑和 2. 主机网关拓扑 + + + +##### Linux 主机设置 + + + +1. Linux 主机应该根据它们各自的发行版文档和您将使用的 Kubernetes 版本的要求进行设置。 + +2. 使用步骤[此处](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/creating-a-linux-master.md)配置Linux主节点 + +3. [可选]安装CNI网络插件。 + + +##### Windows 主机设置 + + + +1. 运行所需 Windows Server 和 Docker 版本的 Windows Server 容器主机。请按照此帮助主题概述的安装说明进行操作:https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server。 + +2. 2. [获取 Windows 二进制文件](#get-windows-binaries) kubelet.exe, kube-proxy.exe, and kubectl.exe 使用说明 + +3. 使用 X.509 密钥从 Linux 主节点复制节点规范文件(kube config) + +4. 创建 HNS 网络,确保正确的 CNI 网络配置,并使用此脚本 [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) 启动 kubelet.exe + +5. 使用此脚本启动 [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) 启动 kube-proxy + +6. [仅限 #2 主机网关模式]使用此脚本 [AddRoutes.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/AddRoutes.ps1) 在Windows主机上添加静态路由 + +更详细的说明可以在[这里](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md)找到。 + + +**Windows CNI 配置示例** + + + +Windows CNI 插件基于 wincni.exe 的,配置文件,是基于上面显示的 ToR 示例图,指定了应用于 Windows node-1 的配置。特别有趣的是 Windows node-1 pod CIDR(10.10.187.64/26) 和 cbr0(10.10.187.66)的关联网关。异常列表指定服务 CIDR(11.0.0.0/8),集群 CIDR(10.10.0.0/16) 和管理(或主机) CIDR(10.127.132.128/25)。 + + +注意:此文件假设用户以前使用 -HNSNetworkcmdlet 在每个 Windows 节点上创建了'l2bridge' 主机网络,如上面链接的 start-kubelet.ps1 和 start-kubeproxy.ps1 脚本中所示 + + +```json +{ + "cniVersion": "0.2.0", + "name": "l2bridge", + "type": "wincni.exe", + "master": "Ethernet", + "ipam": { + "environment": "azure", + "subnet": "10.10.187.64/26", + "routes": [{ + "GW": "10.10.187.66" + }] + }, + "dns": { + "Nameservers": [ + "11.0.0.10" + ] + }, + "AdditionalArgs": [{ + "Name": "EndpointPolicy", + "Value": { + "Type": "OutBoundNAT", + "ExceptionList": [ + "11.0.0.0/8", + "10.10.0.0/16", + "10.127.132.128/25" + ] + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "11.0.0.0/8", + "NeedEncap": true + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "10.127.132.213/32", + "NeedEncap": true + } + } + ] +} +``` + +#### 3.使用覆盖方式打开 vSwitch(OVS) 和开放虚拟网络(OVN) + + + +{{< note >}} +**Note:** 通过 Ansible 剧本的全自动设置是[可用的](https://github.com/openvswitch/ovn-kubernetes/tree/master/contrib)。 +{{< /note >}} + + + +对于手动设置,请继续以下步骤。 + + +##### Linux 主机设置 + + + +设置中心节点和所需组件超出了本文档的范围。您可以阅读[这些说明](https://github.com/openvswitch/ovn-kubernetes#k8s-master-node-initialization)。 + + +添加 Linux minion 也超出了范围,你可以在这里阅读:[Linux minion](https://github.com/openvswitch/ovn-kubernetes#k8s-minion-node-initializations)。 + + + +##### windows 主机设置 + + + +添加 Windows minion 需要您安装 OVS 和 OVN 二进制文件。运行所需 Windows Server 和 Docker 版本的 Windows Server 容器主机。请按照[此帮助主题](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server)概述的设置说明进行操作。从 Windows Server 2016 RTM 开始支持此类部署。 + + +编译 OVS 并生成安装程序不在本文中讨论。请访问[此链接](http://docs.openvswitch.org/en/latest/intro/install/windows/#open-vswitch-on-windows)。对于预构建的认证安装程序,请访问[此链接](https://cloudbase.it/openvswitch/#download)并下载最新版本 + + +以下指南使用预构建的认证安装程序。 + + +安装 OVS 既可以通过 GUI 对话框完成,也可以在无人看管的情况下完成。将 Windows 主机添加到您的设置需要您拥有`OVN主机`和默认安装特性。下面是需要安装的对话框图像: + + +![Windows 安装 OVN OVS](OVN_OVS_Windows_Installer.png) + + + +对于无人看管情况下的安装,请使用以下命令: + + +``` +cmd /c 'msiexec /i openvswitch.msi ADDLOCAL="OpenvSwitchCLI,OpenvSwitchDriver,OVNHost" /qn' +``` + +安装程序设置新的环境变量。请使用命令打开一个新的 shell 或注销/登录,以确保刷新了环境变量。 + + +对于叠加,Windows 上的 OVS 需要透明的 docker 网络才能正常运行。请使用以下命令创建一个透明的 docker 网络,OVS 将使用该网络。powershell: + + +``` +docker network create -d transparent --gateway $GATEWAY_IP --subnet $SUBNET ` + -o com.docker.network.windowsshim.interface="$INTERFACE_ALIAS" external +``` + +$SUBNET 是用于产生 pods 的 minion 子网(将由 kubernetes 使用的子网),$GATEWAY_IP 是 $SUBNET 的第一个 IP,$INTERFACE_ALIAS 是用于创建覆盖隧道的接口(必须与 OVN 主机的 rests 连接)。 +例: + + + +``` +docker network create -d transparent --gateway 10.0.1.1 --subnet 10.0.1.0/24 ` + -o com.docker.network.windowsshim.interface="Ethernet0" external +``` + +创建 docker 网络后,请从 powershell 运行下面的命令。(创建OVS桥接器,在桥接器下添加接口,并启用OVS转发交换机扩展名) + + +``` +$a = Get-NetAdapter | where Name -Match HNSTransparent +Rename-NetAdapter $a[0].Name -NewName HNSTransparent +Stop-Service ovs-vswitchd -force; Disable-VMSwitchExtension "Cloudbase Open vSwitch Extension"; +ovs-vsctl --no-wait del-br br-ex +ovs-vsctl --no-wait --may-exist add-br br-ex +ovs-vsctl --no-wait add-port br-ex HNSTransparent -- set interface HNSTransparent type=internal +ovs-vsctl --no-wait add-port br-ex $INTERFACE_ALIAS +Enable-VMSwitchExtension "Cloudbase Open vSwitch Extension"; sleep 2; Restart-Service ovs-vswitchd +``` + +除此之外,Windows主机的设置与Linux主机相同。从[这里](https://github.com/openvswitch/ovn-kubernetes#k8s-minion-node-initializations)开始执行以下步骤。 + + +**Windows CNI 设置** + + + +现在,Windows OVN&OVS CNI 插件是基于 ovn_cni.exe 可以从[此处](https://cloudbase.it/downloads/ovn_cni.exe)下载。CNI 配置文件示例如下: + + +``` +{ + "name": "net", + "type": "ovn_cni.exe", + "bridge": "br-int", + "isGateway": "true", + "ipMasq": "false", + "ipam": { + "type": "host-local", + "subnet": "$SUBNET" + } +} +``` + +$SUBNET 是上一个 ```docker network create``` 命令中使用的子网。 + + +有关谷歌云平台(GCP),即谷歌计算引擎(GCE)的完整指南,请访问[这里](https://github.com/apprenda/kubernetes-ovn-heterogeneous-cluster#heterogeneous-kubernetes-cluster-on-top-of-ovn)。 + + +有关亚马逊网络服务(AWS),请访问[这里](https://github.com/justeat/kubernetes-windows-aws-ovs#kubernetes-on-windows-in-aws-using-ovn)。 + + +## 启动群集 +要启动集群,您需要启动基于 Linux 的 Kubernetes 控制平面和基于 Windows Server 的 Kubernetes 节点组件(kubelet 和 kube-proxy)。对于 OVS 和 OVN,仅需要 kubelet。 + + + +## 启动基于 Linux-based 的控制平面 +使用您喜欢的方法在 Linux 上启动 Kubernetes 集群。请注意,集群 CIDR 可能需要更新。 + + + +## 支持kubeadm加入 + + + +如果您的群集是由[kubeadm](/docs/setup/independent/create-cluster-kubeadm/),创建的 +使用上面列出的方法之一正确地设置网络(网络是在 kubeadm 之外设置的),您可以使用 kubeadm 向集群添加 Windows 节点。在较高的级别上,首先必须使用 kubeadm(Linux) 初始化主节点,然后设置基于 CNI 的网络(在 kubeadm 之外),最后开始将 Windows 或 Linux 工作节点连接到集群。如需其他文件和参考资料,请访问上文的 kubeadm 链接。 + + + +kubeadm 二进制文件可以在 [Kubernetes 版本](https://github.com/kubernetes/kubernetes/release)的节点二进制文件归档中找到。添加 Windows 节点与添加 Linux 节点没有任何不同: + + + +`kubeadm.exe join --token : --discovery-token-ca-cert-hash sha256:` + +有关更多详细信息请参阅[加入您的节点](/docs/setup/independent/create-cluster-kubeadm/#joining-your-nodes)。 + + +## 支持的功能 + + + +下面列出的示例假设在 Windows Server 1709 上运行 Windows 节点。如果您正在运行 Windows Server 2016,示例将需要更新镜像以指定 `image: microsoft/windowsservercore:ltsc2016`。这是因为在使用进程隔离时,需要容器镜像匹配主机操作系统版本。不指定标记将隐式地使用 `:latest` 标记,这可能导致令人惊讶的行为。有关 Windows Service Core 镜像标记的更多信息,请与[https://hub.docker.com/r/microsoft/windowsservercore/](https://hub.docker.com/r/microsoft/windowsservercore/)联系。 + + + +### 在 Windows 上调度 Pod +由于您的群集同时具有 Linux 和 Windows 节点,因此必须明确设置 nodeSelector 约束以便能够将 pod 安排到 Windows 节点。必须将 nodeSelector 的标签 beta.kubernetes.io/os 设置为值 windows; 请参阅以下示例: + + + +{{< codenew file="windows/simple-pod.yaml" >}} + +{{< note >}} +**Note:** 本例假设您在 Windows Server 1709 上运行,因此使用镜像标记来支持它。如果使用不同的版本,则需要更新标记。例如,如果在 Windows Server 2016 上,更新为使用 `"image": "microsoft/iis"`,默认为该操作系统版本。 +{{< /note >}} + + + +### Secrets 和 ConfigMaps +secret和configmap可以在Windows Service 容器中使用,但是必须作为环境变量使用。有关更多细节,请参见下面的限制部分。 + + + +**例子:** + + + +Windows pod 与 secrets 映射到环境变量 + + +{{< codenew file="windows/secret-pod.yaml" >}} + +具有 configMap 值的 Windows Pod 映射到环境变量 + + +{{< codenew file="windows/configmap-pod.yaml" >}} + +### 卷 +一些受支持的卷挂载可以是本地卷,emptyDir 卷和主机路径卷。需要记住的一点是,路径必须转义,或者使用前斜杠,例如:`mountPath: "C:\\etc\\foo"` or `mountPath: "C:/etc/foo"`。 + + + +对于受支持的卷类型,支持持久卷的声明。 + + +**例子:** + + + +带有主机路径卷的 Windows pod + + +{{< codenew file="windows/hostpath-volume-pod.yaml" >}} + + +具有多个 emptyDir 卷的 Windows pod + + +{{< codenew file="windows/emptydir-pod.yaml" >}} + +### 守护线程集 + + + +支持守护线程集 + + +{{< codenew file="windows/daemonset.yaml" >}} + +### 指标 + + + +Windows Stats 使用混合模型:pod 和容器级别的统计数据来自 CRI(通过 dockershim),而节点级别的统计数据来自“winstats”包,该包使用特定于 Windows 的 perf 计数器导出 cadvisor 之类的数据结构。 + + +### 容器资源 + + + +现在可以为 v1.10 中的 windows 容器设置容器资源(CPU和内存)。 + + +{{< codenew file="windows/deploy-resource.yaml" >}} + +### Hyper-V 容器 + + + +Hyper-V 容器在 v1.10 中作为实验支持。要创建 Hyper-V 容器,kubelet 应该从特性 gates `HyperVContainer=true` 开始,Pod 应该包含注释 `experimental.windows.kubernetes.io/isolation-type=hyperv`。 + + +{{< codenew file="windows/deploy-hyperv.yaml" >}} + +### Kubelet 和 kube-proxy 现在可以作为 Windows 服务运行 + + + +从 kubernetes v1.11 开始,kubelet 和 kube-proxy 可以作为 Windows 服务运行。 + + +这意味着您现在可以通过 `sc` 命令将它们注册为 Windows 服务。有关如何使用 `sc` 创建 Windows 服务的更多细节,请参阅[此处](https://support.microsoft.com/en-us/help/251192/how-to-create-a-windows-service-by-using-sc-exe)。 + + +**例子:** + + + +创建服务 + + +``` +PS > sc.exe create binPath= " --service " +CMD > sc create binPath= " --service " +``` + +请注意,如果参数包含空格,则必须对其进行转义。例: + + +``` +PS > sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " +CMD > sc create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " +``` + +启动服务: + + +``` +PS > Start-Service kubelet; Start-Service kube-proxy +CMD > net start kubelet && net start kube-proxy +``` + +停止服务 + + +``` +PS > Stop-Service kubelet (-Force); Stop-Service kube-proxy (-Force) +CMD > net stop kubelet && net stop kube-proxy +``` + +查询服务 + + +``` +PS > Get-Service kubelet; Get-Service kube-proxy; +CMD > sc.exe queryex kubelet && sc qc kubelet && sc.exe queryex kube-proxy && sc.exe qc kube-proxy +``` + +## Windows Server 容器与 v1.9 的已知限制 + + + +在未来的Kubernetes版本中,社区将解决其中一些限制: + + +- 共享网络名称空间(隔间)与多个 Windows Server 容器(共享内核)每个 pod 只支持在 Windows Server 1709 或更高 + + + +- 不支持使用 secret 和 configmap 作为卷装载 + + + +- Windows不支持挂载传播 + + + +- 不支持有状态应用程序的状态集功能 + + + +- Windows Server 容器 pod 的相同 pod 自动缩放尚未经过验证,pod 端之间无法工作。 + + + +- 不支持Hyper-V隔离容器。 + + + +- Windows 容器操作系统必须与主机操作系统匹配。如果它不这样做,pod 就会陷入崩溃循环。 + + + +- 在 L3 或主机 GW 的网络模型下,由于 Windows 问题,Windows 节点无法访问 + + + +- Windows kubelet.exe 在 VMware Fusion 下运行 Windows Server 时,可能无法启动[issue 57110](https://github.com/kubernetes/kubernetes/pull/57124) + + + +- Flannel 和 Weavenet 尚未得到支持 + + + +- 一些 .Net 核心应用程序希望环境变量的名称中带有冒号 (`:`)。Kubernetes 目前不允许这样做。根据[此处](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration#configuration-by-environment)所述,用双下划线 (`__`) 替换冒号 (':') + + + +- 由于 cgroups 在 windows 上不受支持,kubelet.exe 应该以以下附加参数开始 `--cgroups-per-qos=false --enforce-node-allocatable=""` [issue 61716](https://github.com/kubernetes/kubernetes/issues/61716) + + + +## 后续步骤和资源 + + + +- 对Windows版本的支持从v1.9开始测试,欢迎您提供反馈。有关参与的信息,请访问[SIG-Windows](https://github.com/kubernetes/community/blob/master/sig-windows/README.md) +- 故障排除和常见问题:[链接](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/common-problems) + + diff --git a/content/zh/docs/getting-started-guides/windows/ovn_kubernetes.png b/content/zh/docs/getting-started-guides/windows/ovn_kubernetes.png new file mode 100644 index 0000000000000..739d75aad765c Binary files /dev/null and b/content/zh/docs/getting-started-guides/windows/ovn_kubernetes.png differ diff --git a/content/zh/docs/getting-started-guides/windows/sample-l2bridge-wincni-config.json b/content/zh/docs/getting-started-guides/windows/sample-l2bridge-wincni-config.json new file mode 100644 index 0000000000000..f3842026ce28c --- /dev/null +++ b/content/zh/docs/getting-started-guides/windows/sample-l2bridge-wincni-config.json @@ -0,0 +1,49 @@ +{ + "cniVersion": "0.2.0", + "name": "l2bridge", + "type": "wincni.exe", + "master": "Ethernet", + "ipam": { + "environment": "azure", + "subnet": "10.10.187.64/26", + "routes": [ + { + "GW": "10.10.187.66" + } + ] + }, + "dns": { + "Nameservers": [ + "11.0.0.10" + ] + }, + "AdditionalArgs": [ + { + "Name": "EndpointPolicy", + "Value": { + "Type": "OutBoundNAT", + "ExceptionList": [ + "11.0.0.0/8", + "10.10.0.0/16", + "10.127.132.128/25" + ] + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "11.0.0.0/8", + "NeedEncap": true + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "10.127.132.213/32", + "NeedEncap": true + } + } + ] +} diff --git a/content/zh/docs/getting-started-guides/windows/windows-setup.png b/content/zh/docs/getting-started-guides/windows/windows-setup.png new file mode 100644 index 0000000000000..e11c58d596e35 Binary files /dev/null and b/content/zh/docs/getting-started-guides/windows/windows-setup.png differ diff --git a/content/zh/docs/home/supported-doc-versions.md b/content/zh/docs/home/supported-doc-versions.md index eae8ac97b162c..986155dc0f145 100644 --- a/content/zh/docs/home/supported-doc-versions.md +++ b/content/zh/docs/home/supported-doc-versions.md @@ -9,13 +9,13 @@ card: {{% capture overview %}} -本网站包含了当前最新版本和之前四个版本的 Kubernetes。 +本网站包含当前版本和之前四个版本的 Kubernetes 文档。 {{% /capture %}} {{% capture body %}} -## 当前最新版本 +## 当前版本 当前版本是 [{{< param "version" >}}](/)。 diff --git a/content/zh/docs/reference/access-authn-authz/_index.md b/content/zh/docs/reference/access-authn-authz/_index.md index 1e1d30cfb1ea3..aa4d8d273055a 100644 --- a/content/zh/docs/reference/access-authn-authz/_index.md +++ b/content/zh/docs/reference/access-authn-authz/_index.md @@ -2,4 +2,4 @@ title: 访问 API weight: 20 toc-hide: true ---- \ No newline at end of file +--- diff --git a/content/zh/docs/reference/access-authn-authz/abac.md b/content/zh/docs/reference/access-authn-authz/abac.md index 4c3715e495faf..196e541660cf7 100644 --- a/content/zh/docs/reference/access-authn-authz/abac.md +++ b/content/zh/docs/reference/access-authn-authz/abac.md @@ -20,36 +20,36 @@ content_template: templates/concept 基于 `ABAC` 模式,可以这样指定策略文件 `--authorization-policy-file=SOME_FILENAME`。 -此文件是 JSON 格式[每行都是一个JSON对象](http://jsonlines.org/),不应存在封闭的列表或映射,每行只有一个映射。 - -每一行都是一个 "策略对象",策略对象是具有以下映射的属性: - - - 版本控制属性: - - `apiVersion`,字符串类型: 有效值为"abac.authorization.kubernetes.io/v1beta1",允许版本控制和转换策略格式。 - - `kind`,字符串类型: 有效值为 "Policy",允许版本控制和转换策略格式。 - - `spec` 配置为具有以下映射的属性: - - 匹配属性: - - `user`,字符串类型; 来自 `--token-auth-file` 的用户字符串,如果你指定`user`,它必须与验证用户的用户名匹配。 - - `group`,字符串类型; 如果指定`group`,它必须与经过身份验证的用户的一个组匹配,`system:authenticated`匹配所有经过身份验证的请求。`system:unauthenticated`匹配所有未经过身份验证的请求。 - - 资源匹配属性: - - `apiGroup`,字符串类型; 一个 API 组。 - - 例: `extensions` - - 通配符: `*`匹配所有 API 组。 - - `namespace`,字符串类型; 一个命名空间。 - - 例如: `kube-system` - - 通配符: `*` 匹配所有资源请求。 - - `resource`,字符串类型; 资源类型。 - - 例:`pods` - - 通配符: `*`匹配所有资源请求。 - - 非资源匹配属性: - - `nonResourcePath`,字符串类型; 非资源请求路径。 - - 例如:`/version`或`/apis` - - 通配符: +此文件是 JSON 格式[每行都是一个 JSON 对象](http://jsonlines.org/),不应存在封闭的列表或映射,每行只有一个映射。 + +每一行都是一个 " 策略对象 ",策略对象是具有以下映射的属性 : + + - 版本控制属性 : + - `apiVersion`,字符串类型 : 有效值为 "abac.authorization.kubernetes.io/v1beta1",允许版本控制和转换策略格式。 + - `kind`,字符串类型 : 有效值为 "Policy",允许版本控制和转换策略格式。 + - `spec` 配置为具有以下映射的属性 : + - 匹配属性 : + - `user`,字符串类型 ; 来自 `--token-auth-file` 的用户字符串,如果你指定 `user`,它必须与验证用户的用户名匹配。 + - `group`,字符串类型 ; 如果指定 `group`,它必须与经过身份验证的用户的一个组匹配,`system:authenticated` 匹配所有经过身份验证的请求。`system:unauthenticated` 匹配所有未经过身份验证的请求。 + - 资源匹配属性 : + - `apiGroup`,字符串类型 ; 一个 API 组。 + - 例 : `extensions` + - 通配符 : `*` 匹配所有 API 组。 + - `namespace`,字符串类型 ; 一个命名空间。 + - 例如 : `kube-system` + - 通配符 : `*` 匹配所有资源请求。 + - `resource`,字符串类型 ; 资源类型。 + - 例 :`pods` + - 通配符 : `*` 匹配所有资源请求。 + - 非资源匹配属性 : + - `nonResourcePath`,字符串类型 ; 非资源请求路径。 + - 例如 :`/version` 或 `/apis` + - 通配符 : - `*` 匹配所有非资源请求。 - - `/foo/*` 匹配`/foo/`的所有子路径。 + - `/foo/*` 匹配 `/foo/` 的所有子路径。 - `readonly`,键入 boolean,如果为 true,则表示该策略仅适用于 get,list 和 watch 操作。 -**注意:** 未设置的属性与类型设置为零值的属性相同(例如空字符串,0、false),然而未知的应该可读性优先。 +**注意 :** 未设置的属性与类型设置为零值的属性相同 ( 例如空字符串,0、false),然而未知的应该可读性优先。 在将来,策略可能以 JSON 格式表示,并通过 REST 界面进行管理。 @@ -57,58 +57,58 @@ content_template: templates/concept 请求具有与策略对象的属性对应的属性。 -当接收到请求时,确定属性。 未知属性设置为其类型的零值(例如: 空字符串,0,false)。 +当接收到请求时,确定属性。 未知属性设置为其类型的零值(例如 : 空字符串,0,false)。 -设置为`“*"`的属性将匹配相应属性的任何值。 +设置为 `"*"` 的属性将匹配相应属性的任何值。 检查属性的元组,以匹配策略文件中的每个策略。 如果至少有一行匹配请求属性,则请求被授权(但可能会在稍后验证失败)。 -要允许任何经过身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authenticated“`。 +要允许任何经过身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authenticated"`。 -要允许任何未经身份验证的用户执行某些操作,请将策略组属性设置为`"system:authentication“`。 +要允许任何未经身份验证的用户执行某些操作,请将策略组属性设置为 `"system:authentication"`。 要允许用户执行任何操作,请使用 apiGroup,命名空间, -资源和 nonResourcePath 属性设置为 `“*"`的策略. +资源和 nonResourcePath 属性设置为 `"*"` 的策略。 -要允许用户执行任何操作,请使用设置为`“*”` 的 apiGroup,namespace,resource 和 nonResourcePath 属性编写策略。 +要允许用户执行任何操作,请使用设置为 `"*"` 的 apiGroup,namespace,resource 和 nonResourcePath 属性编写策略。 ## Kubectl -Kubectl 使用 api-server 的 `/api` 和 `/apis` 端点进行协商客户端/服务器版本。 通过创建/更新来验证发送到API的对象操作,kubectl 查询某些 swagger 资源。 对于API版本"v1", 那就是`/swaggerapi/api/v1` & `/swaggerapi/ experimental/v1`。 +Kubectl 使用 api-server 的 `/api` 和 `/apis` 端点进行协商客户端 / 服务器版本。 通过创建 / 更新来验证发送到 API 的对象操作,kubectl 查询某些 swagger 资源。 对于 API 版本 "v1", 那就是 `/swaggerapi/api/v1` & `/swaggerapi/ experimental/v1`。 -当使用 ABAC 授权时,这些特殊资源必须明确通过策略中的 `nonResourcePath` 属性暴露出来(参见下面的[例子](#examples)): +当使用 ABAC 授权时,这些特殊资源必须明确通过策略中的 `nonResourcePath` 属性暴露出来 ( 参见下面的[例子](#examples)): -* `/api`,`/api/*`,`/apis`和`/apis/*` 用于 API 版本协商. -* `/version` 通过 `kubectl version` 检索服务器版本. -* `/swaggerapi/*` 用于创建/更新操作. +* `/api`,`/api/*`,`/apis` 和 `/apis/*` 用于 API 版本协商。 +* `/version` 通过 `kubectl version` 检索服务器版本。 +* `/swaggerapi/*` 用于创建 / 更新操作。 -要检查涉及到特定kubectl操作的HTTP调用,您可以调整详细程度: +要检查涉及到特定 kubectl 操作的 HTTP 调用,您可以调整详细程度: kubectl --v=8 version ## 例子 -1. Alice 可以对所有资源做任何事情: +1. Alice 可以对所有资源做任何事情 : ```json {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}} ``` -2. Kubelet 可以读取任何pod: +2. Kubelet 可以读取任何 pod: ```json {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}} ``` -3. Kubelet 可以读写事件: +3. Kubelet 可以读写事件 : ```json {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}} ``` -4. Bob 可以在命名空间“projectCaribou"中读取 pod: +4. Bob 可以在命名空间 “projectCaribou” 中读取 pod: ```json {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}} ``` -5. 任何人都可以对所有非资源路径进行只读请求: +5. 任何人都可以对所有非资源路径进行只读请求: ```json {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}} @@ -119,7 +119,7 @@ Kubectl 使用 api-server 的 `/api` 和 `/apis` 端点进行协商客户端/服 ## 服务帐户的快速说明 -服务帐户自动生成用户。 用户名是根据命名约定生成的: +服务帐户自动生成用户。 用户名是根据命名约定生成的: ```shell system:serviceaccount:: @@ -130,13 +130,13 @@ system:serviceaccount:: system:serviceaccount::default ``` -例如,如果要将 API 的 kube-system 完整权限中的默认服务帐户授予,则可以将此行添加到策略文件中: +例如,如果要将 API 的 kube-system 完整权限中的默认服务帐户授予,则可以将此行添加到策略文件中 : ```json {"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}} ``` -需要重新启动 apiserver 以获取新的策略行. +需要重新启动 apiserver 以获取新的策略行。 {{% /capture %}} diff --git a/content/zh/docs/reference/access-authn-authz/authorization.md b/content/zh/docs/reference/access-authn-authz/authorization.md index 8ca313af0138f..4e13befdf963f 100644 --- a/content/zh/docs/reference/access-authn-authz/authorization.md +++ b/content/zh/docs/reference/access-authn-authz/authorization.md @@ -28,12 +28,12 @@ that Kubernetes authorization works with existing organization-wide or cloud-provider-wide access control systems which may handle other APIs besides the Kubernetes API. --> -在Kubernetes中,您必须在授权(授予访问权限)之前进行身份验证(登录),有关身份验证的信息, +在 Kubernetes 中,您必须在授权(授予访问权限)之前进行身份验证(登录),有关身份验证的信息, 请参阅 [访问控制概述](/docs/reference/access-authn-authz/controlling-access/). -Kubernetes期望REST API请求中常见的属性。 -这意味着Kubernetes授权适用于现有的组织范围或云提供商范围的访问控制系统, -除了Kubernetes API之外,它还可以处理其他API。 +Kubernetes 期望 REST API 请求中常见的属性。 +这意味着 Kubernetes 授权适用于现有的组织范围或云提供商范围的访问控制系统, +除了 Kubernetes API 之外,它还可以处理其他 API。 ## 审查您的请求属性 -Kubernetes仅审查以下API请求属性: +Kubernetes 仅审查以下 API 请求属性: - * **user** - 身份验证期间提供的`user`字符串。 + * **user** - 身份验证期间提供的 `user` 字符串。 * **group** - 经过身份验证的用户所属的组名列表。 * **extra** - 由身份验证层提供的任意字符串键到字符串值的映射。 * **API** - 指示请求是否针对 API 资源。 - * **Request path** - 各种非资源端点的路径,如`/api`或`/healthz`。 - * **API request verb** - API 动词`get`,`list`,`create`,`update`,`patch`,`watch`,`proxy`,`redirect`,`delete`和`deletecollection`用于资源请求。要确定资源API端点的请求动词,请参阅[确定请求动词](/docs/reference/access-authn-authz/authorization/#determine-whether-a-request-is-allowed-or-denied)。 - * **HTTP request verb** - HTTP 动词`get`,`post`,`put`和`delete`用于非资源请求。 - * **Resource** - 正在访问的资源的 ID 或名称(仅限资源请求) - 对于使用`get`,`update`,`patch`和`delete`动词的资源请求,您必须提供资源名称。 + * **Request path** - 各种非资源端点的路径,如 `/api` 或 `/healthz`。 + * **API request verb** - API 动词 `get`,`list`,`create`,`update`,`patch`,`watch`,`proxy`,`redirect`,`delete` 和 `deletecollection` 用于资源请求。要确定资源 API 端点的请求动词,请参阅[确定请求动词](/docs/reference/access-authn-authz/authorization/#determine-whether-a-request-is-allowed-or-denied)。 + * **HTTP request verb** - HTTP 动词 `get`,`post`,`put` 和 `delete` 用于非资源请求。 + * **Resource** - 正在访问的资源的 ID 或名称(仅限资源请求) - 对于使用 `get`,`update`,`patch` 和 `delete` 动词的资源请求,您必须提供资源名称。 * **Subresource** - 正在访问的子资源(仅限资源请求)。 * **Namespace** - 正在访问的对象的名称空间(仅适用于命名空间资源请求)。 - * **API group** - 正在访问的 API 组(仅限资源请求)。空字符串表示[核心API组](/docs/concepts/overview/kubernetes-api/)。 + * **API group** - 正在访问的 API 组(仅限资源请求)。空字符串表示[核心 API 组](/docs/concepts/overview/kubernetes-api/)。 -#### 检查API访问 +#### 检查 API 访问 -`kubectl`提供`auth can-i`子命令,用于快速查询 API 授权层。 -该命令使用`SelfSubjectAccessReview` API来确定当前用户是否可以执行给定操作,并且无论使用何种授权模式都可以工作。 +`kubectl` 提供 `auth can-i` 子命令,用于快速查询 API 授权层。 +该命令使用 `SelfSubjectAccessReview` API 来确定当前用户是否可以执行给定操作,并且无论使用何种授权模式都可以工作。 ```bash $ kubectl auth can-i create deployments --namespace dev @@ -192,14 +192,14 @@ These APIs can be queried by creating normal Kubernetes resources, where the res field of the returned object is the result of the query. --> -`SelfSubjectAccessReview`是`authorization.k8s.io` API组的一部分,它将 API 服务器授权公开给外部服务。 +`SelfSubjectAccessReview` 是 `authorization.k8s.io` API 组的一部分,它将 API 服务器授权公开给外部服务。 该组中的其他资源包括: -* `SubjectAccessReview` - 访问任何用户的 Review ,而不仅仅是当前用户。用于将授权决策委派给API服务器。例如,kubelet 和扩展 API 服务器使用它来确定用户对自己的API的访问权限。 -* `LocalSubjectAccessReview` - 与`SubjectAccessReview`类似,但仅限于特定的命名空间。 -* `SelfSubjectRulesReview` - 返回用户可在命名空间内执行的操作集的审阅。用户可以快速汇总自己的访问权限,或者用于隐藏/显示操作的UI。 +* `SubjectAccessReview` - 访问任何用户的 Review ,而不仅仅是当前用户。用于将授权决策委派给 API 服务器。例如,kubelet 和扩展 API 服务器使用它来确定用户对自己的 API 的访问权限。 +* `LocalSubjectAccessReview` - 与 `SubjectAccessReview` 类似,但仅限于特定的命名空间。 +* `SelfSubjectRulesReview` - 返回用户可在命名空间内执行的操作集的审阅。用户可以快速汇总自己的访问权限,或者用于 UI 中的隐藏/显示动作。 -可以通过创建普通 Kubernetes 资源来查询这些 API ,其中返回对象的响应“status”字段是查询的结果。 +可以通过创建普通 Kubernetes 资源来查询这些 API ,其中返回对象的响应 “status” 字段是查询的结果。 ```bash $ kubectl create -f - -o yaml << EOF @@ -247,20 +247,20 @@ You can choose more than one authorization module. Modules are checked in order so an earlier module has higher priority to allow or deny a request. --> -## 为您的授权模块使用标志 +## 为您的授权模块应用参数 -您必须在策略中包含一个标志,以指明您的策略包含哪个授权模块: +您必须在策略中包含一个参数标志,以指明您的策略包含哪个授权模块: -可以使用以下标志: +可以使用以下参数: * `--authorization-mode=ABAC` 基于属性的访问控制(ABAC)模式允许您使用本地文件配置策略。 * `--authorization-mode=RBAC` 基于角色的访问控制(RBAC)模式允许您使用 Kubernetes API 创建和存储策略。 - * `--authorization-mode=Webhook` WebHook 是一种 HTTP 回调模式,允许您使用远程REST端点管理授权。 - * `--authorization-mode=Node` 节点授权是一种特殊用途的授权模式,专门授权由 kubelet 发出的API请求。 + * `--authorization-mode=Webhook` WebHook 是一种 HTTP 回调模式,允许您使用远程 REST 端点管理授权。 + * `--authorization-mode=Node` 节点授权是一种特殊用途的授权模式,专门授权由 kubelet 发出的 API 请求。 * `--authorization-mode=AlwaysDeny` 该标志阻止所有请求。仅将此标志用于测试。 * `--authorization-mode=AlwaysAllow` 此标志允许所有请求。仅在您不需要 API 请求的授权时才使用此标志。 -您可以选择多个授权模块。按顺序检查模块,以便较早的模块具有更高的优先级来允许或拒绝请求。 +您可以选择多个授权模块。模块按顺序检查,以便较早的模块具有更高的优先级来允许或拒绝请求。 -## 通过pod创建权限升级 +## 通过 Pod 创建升级权限 -能够在命名空间中创建 pod 的用户可能会升级其在该命名空间内的权限。 -他们可以创建在该命名空间内访问其权限的 pod 。 -他们可以创建用户无法自己读取 secret 的 pod ,或者在具有不同/更高权限的服务帐户下运行的 pod 。 +能够在命名空间中创建 Pod 的用户可能会升级其在该命名空间内的权限。 +他们可以创建在该命名空间内访问其权限的 Pod 。 +他们可以创建用户无法自己读取 secret 的 Pod ,或者在具有不同/更高权限的服务帐户下运行的 Pod 。 {{< caution >}} -**注意:** 系统管理员在授予对 pod 创建的访问权限时要小心。 -授予在命名空间中创建 pod(或创建pod的控制器)的权限的用户可以: -读取命名空间中的所有秘密;读取命名空间中的所有配置映射; +**注意:** 系统管理员在授予对 Pod 创建的访问权限时要小心。 +授予在命名空间中创建 Pod(或创建 Pod 的控制器)的权限的用户可以: +读取命名空间中的所有 secret;读取命名空间中的所有 ConfigMap; 并模拟命名空间中的任何服务帐户并执行帐户可以执行的任何操作。 无论采用何种授权方式,这都适用。 {{< /caution >}} @@ -299,6 +299,6 @@ mode. * To learn more about Authentication, see **Authentication** in [Controlling Access to the Kubernetes API](/docs/reference/access-authn-authz/controlling-access/). * To learn more about Admission Control, see [Using Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/). --> -* 要了解有关身份验证的更多信息,请参阅 **身份验证** [控制对Kubernetes API的访问](/docs/reference/access-authn-authz/controlling-access/). -* 要了解有关准入控制的更多信息,请参阅 [使用准入控制器](/docs/reference/access-authn-authz/admission-controllers/). +* 要了解有关身份验证的更多信息,请参阅 **身份验证** [控制对 Kubernetes API 的访问](/docs/reference/access-authn-authz/controlling-access/)。 +* 要了解有关准入控制的更多信息,请参阅 [使用准入控制器](/docs/reference/access-authn-authz/admission-controllers/)。 {{% /capture %}} \ No newline at end of file diff --git a/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md b/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md index ced000932de16..77ca6f32d520f 100644 --- a/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md +++ b/content/zh/docs/reference/access-authn-authz/bootstrap-tokens.md @@ -15,8 +15,8 @@ Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 启动引导令牌被定义成一个特定类型的 secrets(`bootstrap.kubernetes.io/token`),并存在于 `kube-system` 命名空间中。然后这些 secrets 会被 API 服务器上的启动引导的认证器读取。 -控制器管理器中的控制器TokenCleaner能够删除过期的令牌。在节点发现的过程中Kubernetes会使用特殊的ConfigMap对象。 -控制器管理器中的BootstrapSigner控制器也会使用启动引导令牌为这类对象生成签名信息。 +控制器管理器中的控制器 TokenCleaner 能够删除过期的令牌。在节点发现的过程中 Kubernetes 会使用特殊的 ConfigMap 对象。 +控制器管理器中的 BootstrapSigner 控制器也会使用启动引导令牌为这类对象生成签名信息。 目前,启动引导令牌处于 **alpha** 阶段,但是预期也不会有大的突破性变化。 @@ -26,7 +26,7 @@ Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 系统进行工作。 更加规范地说,它们必须符合正则表达式 `[a-z0-9]{6}\.[a-z0-9]{16}`。 令牌的第一部分是 "Token ID" ,它是公共信息。用于引用某个令牌,并确保不会泄露认证所使用的秘密信息。 -第二部分是 "令牌秘密(Token Secret)",它应该被共享给收信的第三方。 +第二部分是“令牌秘密(Token Secret)”,它应该被共享给收信的第三方。 ## 启用启动引导令牌 @@ -82,19 +82,19 @@ TokenCleaner 控制器会删除过期的令牌。 ## 使用 `kubeadm` 管理令牌 -你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`) +你可以使用 `kubeadm` 工具管理正在运行集群的令牌。它会从 `kubeadm` 创建的集群(`/etc/kubernetes/admin.conf`) 自动抓取默认管理员密码。你可以通过参数 `--kubeconfig` 对下面命令指定一个另外的 kubeconfig 文件抓取密码。 * `kubeadm token list` 列举了令牌,同时显示了它们的过期时间和用途。 * `kubeadm token create` 创建一个新令牌。 * `--description` 设置新令牌的描述。 - * `--ttl duration` 设置令牌从 "现在" 起到过期时间的差值。 + * `--ttl duration` 设置令牌从“现在”起到过期时间的差值。 默认是 0 ,也就是不过期。 * `--usages` 设置令牌被使用的方式。默认是 `signing,authentication`。用途在上面已经描述。 * `kubeadm token delete |.` 删除令牌。 令牌可以只用 ID 来确认,也可以用整个令牌的值。如果只用 ID 的情况下,密文不匹配的令牌也会被删除。 -### ConfigMap签名 +### ConfigMap 签名 除了认证之外,令牌可以用于签名 ConfigMap。这在集群启动过程的早期,在客户端信任 API 服务器之前被使用。 被签名的 ConfigMap 可以通过共享令牌被认证。 @@ -131,6 +131,6 @@ ConfigMap 的 `kubeconfig` 成员是一个填好了集群信息的配置文件 这里主要交换的信息是 `certificate-authority-data`。在将来可能会有扩展。 签名是一个 JWS 签名,使用了 "detached" 模式。为了检验签名,用户应该按照 JWS 规则 -(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间 +(base64 编码而忽略结尾的 `=`)对 `kubeconfig` 的载荷进行编码。完成编码的载荷会被通过插入 JWS 并存在于两个点的中间 ,用于形成一个完整的 JWS。可以使用令牌的完整信息(比如 `07401b.f395accd246ae52d`)作为共享密钥, 通过 `HS256` 方式 (HMAC-SHA256) 对 JWS 进行校验。 用户 _必须_ 确保使用了 HS256。 diff --git a/content/zh/docs/reference/access-authn-authz/controlling-access.md b/content/zh/docs/reference/access-authn-authz/controlling-access.md index 251b69484d781..e181571a5de5f 100644 --- a/content/zh/docs/reference/access-authn-authz/controlling-access.md +++ b/content/zh/docs/reference/access-authn-authz/controlling-access.md @@ -2,40 +2,40 @@ approvers: - erictune - lavalamp -title: Kubernetes API访问控制 +title: Kubernetes API 访问控制 --- -用户通过 `kubectl`、客户端库或者通过发送REST请求[访问API](/docs/user-guide/accessing-the-cluster)。 用户(自然人)和[Kubernetes服务账户](/docs/tasks/configure-pod-container/configure-service-account/) 都可以被授权进行API访问。 -请求到达API服务器后会经过几个阶段,具体说明如图: +用户通过 `kubectl`、客户端库或者通过发送 REST 请求[访问 API](/docs/user-guide/accessing-the-cluster)。 用户(自然人)和 [Kubernetes 服务账户](/docs/tasks/configure-pod-container/configure-service-account/) 都可以被授权进行 API 访问。 +请求到达 API 服务器后会经过几个阶段,具体说明如图: ![Diagram of request handling steps for Kubernetes API request](/images/docs/admin/access-control-overview.svg) ## 传输层安全 -在典型的Kubernetes集群中,API通过443端口提供服务。 -API服务器会提供一份证书。 该证书一般是自签名的, 所以用户机器上的 `$USER/.kube/config` 目录通常 -包含该API服务器证书的根证书,用来代替系统默认根证书。 当用户使用 `kube-up.sh` 创建集群时,该证书通常会被自动写入用户的`$USER/.kube/config`。 如果集群中存在多个用户,则创建者需要与其他用户共享证书。 +在典型的 Kubernetes 集群中,API 通过 443 端口提供服务。 +API 服务器会提供一份证书。 该证书一般是自签名的, 所以用户机器上的 `$USER/.kube/config` 目录通常 +包含该 API 服务器证书的根证书,用来代替系统默认根证书。 当用户使用 `kube-up.sh` 创建集群时,该证书通常会被自动写入用户的 `$USER/.kube/config`。 如果集群中存在多个用户,则创建者需要与其他用户共享证书。 ## 认证 -一旦 TLS 连接建立,HTTP请求就进入到了认证的步骤。即图中的步骤 **1** 。 -集群创建脚本或集群管理员会为API服务器配置一个或多个认证模块。 -更具体的认证相关的描述详见 [这里](/docs/admin/authentication/)。 +一旦 TLS 连接建立,HTTP 请求就进入到了认证的步骤。即图中的步骤 **1** 。 +集群创建脚本或集群管理员会为 API 服务器配置一个或多个认证模块。 +更具体的认证相关的描述详见[这里](/docs/admin/authentication/)。 -认证步骤的输入是整个HTTP请求,但这里通常只是检查请求头和/或客户端证书。 +认证步骤的输入是整个 HTTP 请求,但这里通常只是检查请求头和 / 或客户端证书。 -认证模块支持客户端证书,密码和Plain Tokens, -Bootstrap Tokens,以及JWT Tokens (用于服务账户)。 +认证模块支持客户端证书,密码和 Plain Tokens, +Bootstrap Tokens,以及 JWT Tokens(用于服务账户)。 (管理员)可以同时设置多种认证模块,在设置了多个认证模块的情况下,每个模块会依次尝试认证, 直到其中一个认证成功。 -在 GCE 平台中,客户端证书,密码和Plain Tokens,Bootstrap Tokens,以及JWT Tokens同时被启用。 +在 GCE 平台中,客户端证书,密码和 Plain Tokens,Bootstrap Tokens,以及 JWT Tokens 同时被启用。 -如果请求认证失败,则请求被拒绝,返回401状态码。 +如果请求认证失败,则请求被拒绝,返回 401 状态码。 如果认证成功,则被认证为具体的 `username`,该用户名可供随后的步骤中使用。一些认证模块还提供了用户的组成员关系,另一些则没有。 -尽管Kubernetes使用 "用户名" 来进行访问控制和请求记录,但它实际上并没有 `user` 对象,也不存储用户名称或其他相关信息。 +尽管 Kubernetes 使用“用户名”来进行访问控制和请求记录,但它实际上并没有 `user` 对象,也不存储用户名称或其他相关信息。 ## 授权 @@ -43,7 +43,7 @@ Bootstrap Tokens,以及JWT Tokens (用于服务账户)。 请求须包含请求者的用户名,请求动作,以及该动作影响的对象。 如果存在相应策略,声明该用户具有进行相应操作的权限,则该请求会被授权。 -例如,如果Bob有如下策略,那么他只能够读取`projectCaribou`命名空间下的pod资源: +例如,如果 Bob 有如下策略,那么他只能够读取 `projectCaribou` 命名空间下的 pod 资源: ```json { @@ -57,7 +57,7 @@ Bootstrap Tokens,以及JWT Tokens (用于服务账户)。 } } ``` -如果Bob发起以下请求,那么请求能够通过授权,因为Bob被允许访问 `projectCaribou` 命名空间下的对象: +如果 Bob 发起以下请求,那么请求能够通过授权,因为 Bob 被允许访问 `projectCaribou` 命名空间下的对象: ```json { @@ -73,20 +73,20 @@ Bootstrap Tokens,以及JWT Tokens (用于服务账户)。 } } ``` -如果Bob对 `projectCaribou` 命名空间下的对象发起一个写(`create` 或者 `update`)请求,那么它的授权会被拒绝。 如果Bob请求读取(`get`) 其他命名空间,例如 `projectFish`下的对象,其授权也会被拒绝。 +如果 Bob 对 `projectCaribou` 命名空间下的对象发起一个写(`create` 或者 `update`)请求,那么它的授权会被拒绝。 如果 Bob 请求读取 (`get`)其他命名空间,例如 `projectFish` 下的对象,其授权也会被拒绝。 -Kubernetes的授权要求使用通用的REST属性与现有的组织或云服务提供商的访问控制系统进行交互。 采用REST格式是必要的,因为除Kubernetes外,这些访问控制系统还可能与其他的API进行交互。 +Kubernetes 的授权要求使用通用的 REST 属性与现有的组织或云服务提供商的访问控制系统进行交互。 采用 REST 格式是必要的,因为除 Kubernetes 外,这些访问控制系统还可能与其他的 API 进行交互。 -Kubernetes 支持多种授权模块,例如ABAC模式,RBAC模式和 Webhook模式。 管理员创建集群时,会配置API服务器应用的授权模块。 如果多种授权模式同时被启用,Kubernetes将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。 +Kubernetes 支持多种授权模块,例如 ABAC 模式,RBAC 模式和 Webhook 模式。 管理员创建集群时,会配置 API 服务器应用的授权模块。 如果多种授权模式同时被启用,Kubernetes 将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP 状态码 403)。 -要了解更多的Kubernetes授权相关信息,包括使用授权模块创建策略的具体说明等,可参考[授权概述](/docs/admin/authorization)。 +要了解更多的 Kubernetes 授权相关信息,包括使用授权模块创建策略的具体说明等,可参考[授权概述](/docs/admin/authorization)。 ## 准入控制 准入控制模块是能够修改或拒绝请求的软件模块。 作为授权模块的补充,准入控制模块会访问被创建或更新的对象的内容。 -它们作用于对象的创建,删除,更新和连接 (proxy)阶段,但不包括对象的读取。 +它们作用于对象的创建,删除,更新和连接(proxy)阶段,但不包括对象的读取。 可以同时配置多个准入控制器,它们会按顺序依次被调用。 @@ -98,23 +98,23 @@ Kubernetes 支持多种授权模块,例如ABAC模式,RBAC模式和 Webhook 可用的准入控制模块描述 [如下](/docs/admin/admission-controllers/)。 -一旦请求通过所有准入控制器,将使用对应API对象的验证流程对其进行验证,然后写入对象存储 (如步骤 **4**)。 +一旦请求通过所有准入控制器,将使用对应 API 对象的验证流程对其进行验证,然后写入对象存储 (如步骤 **4**)。 -## API的端口和IP +## API 的端口和 IP -上述讨论适用于发送请求到API服务器的安全端口(典型情况)。 -实际上API服务器可以通过两个端口提供服务: +上述讨论适用于发送请求到 API 服务器的安全端口(典型情况)。 +实际上 API 服务器可以通过两个端口提供服务: -默认情况下,API服务器在2个端口上提供HTTP服务: +默认情况下,API 服务器在 2 个端口上提供 HTTP 服务: 1. `Localhost Port`: - 用于测试和启动,以及管理节点的其他组件 - (scheduler, controller-manager)与API的交互 - - 没有TLS - - 默认值为8080,可以通过 `--insecure-port` 标记来修改。 - - 默认的IP地址为localhost, 可以通过 `--insecure-bind-address`标记来修改。 + (scheduler, controller-manager)与 API 的交互 + - 没有 TLS + - 默认值为 8080,可以通过 `--insecure-port` 标记来修改。 + - 默认的 IP 地址为 localhost, 可以通过 `--insecure-bind-address` 标记来修改。 - 请求会 **绕过** 认证和鉴权模块。 - 请求会被准入控制模块处理。 - 其访问需要主机访问的权限。 @@ -123,12 +123,12 @@ Kubernetes 支持多种授权模块,例如ABAC模式,RBAC模式和 Webhook - 尽可能使用该端口访问 - 应用 TLS。 可以通过 `--tls-cert-file` 设置证书, 通过 `--tls-private-key-file` 设置私钥。 - - 默认值为6443,可以通过 `--secure-port` 标记来修改。 - - 默认IP是首个非本地的网络接口地址,可以通过 `--bind-address` 标记来修改。 + - 默认值为 6443,可以通过 `--secure-port` 标记来修改。 + - 默认 IP 是首个非本地的网络接口地址,可以通过 `--bind-address` 标记来修改。 - 请求会经过认证和鉴权模块处理。 - 请求会被准入控制模块处理。 - 要求认证和授权模块正常运行。 -通过 `kube-up.sh`创建集群时, 对 Google Compute Engine (GCE) -和一些其他的云供应商来说, API通过443端口提供服务。 对 -GCE而言,项目上配置了防火墙规则,允许外部的HTTPS请求访问API,其他(厂商的)集群设置方法各不相同。 +通过 `kube-up.sh` 创建集群时, 对 Google Compute Engine(GCE) +和一些其他的云供应商来说, API 通过 443 端口提供服务。 对 +GCE 而言,项目上配置了防火墙规则,允许外部的 HTTPS 请求访问 API,其他(厂商的)集群设置方法各不相同。 diff --git a/content/zh/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/zh/docs/reference/access-authn-authz/extensible-admission-controllers.md new file mode 100644 index 0000000000000..ccaebb936fb9d --- /dev/null +++ b/content/zh/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -0,0 +1,330 @@ +--- +reviewers: +- smarterclayton +- lavalamp +- whitlockjc +- caesarxuchao +- deads2k +- liggitt +- mbohlool + +title: 动态准入控制 +content_template: templates/concept +weight: 40 +--- + +{{% capture overview %}} + +[admission 控制器文档](/docs/reference/access-authn-authz/admission-controllers/) +介绍如何使用标准的插件式 admission 控制器。然而, +由于以下原因插件 admission 控制器对于所有用例来说都不够灵活: + +* 他们需要编译到 kube-apiserver 里面。 +* 它们仅在 apiserver 启动时可配置。 + +*Admission Webhooks*(1.9 版中的 beta)解决了这些限制。 +它允许 admission 控制器能被独立开发以及在运行时配置。 + +本页介绍如何使用 Admission Webhooks。 +{{% /capture %}} + +{{% capture body %}} + +### 什么是 admission webhook? + + +Admission webhooks 是 HTTP 回调,它接收 admission 请求并对它们做一些事情。 +您可以定义两种类型的 admission webhook, +[validating admission Webhook](/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook) +和 +[mutating admission webhook](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)。 +通过 validating admission Webhook,您可以拒绝请求以执行自定义的 admission 策略。 +通过 mutating admission webhook,您可以更改请求以执行自定义的默认值。 + + +### 尝试 admission webhook + +admission webhook 本质上是集群控制平面的一部分。 您应该非常谨慎地编写和部署它们。 +如果您打算编写/部署生产级 admission webhook,请阅读[用户指南](/docs/reference/access-authn-authz/extensible-admission-controllers/#write-an-admission-webhook-server)以获取相关说明。 +在下文中,我们将介绍如何快速试验 admission webhook。 + + +### 先决条件 + +* 确保 Kubernetes 集群版本至少为 v1.9。 + +* 确保启用 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 控制器。 + [这里](/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended-set-of-admission-controllers-to-use) + 是一组推荐的 admission 控制器,通常可以启用。 + +* 确保启用了`admissionregistration.k8s.io/v1beta1` API。 + + +### 编写一个admission webhook 服务器 + +请参阅 Kubernetes e2e 测试中的 +[admission webhook 服务器](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/images/webhook/main.go)实现。 + webhook 处理由 apiservers 发送的 `admissionReview` 请求,并将其决定包含在 `admissionResponse` 中发回。 + +`admissionReview` 请求可以有不同的版本(例如,`v1beta1` 或未来版本中的 `v1`)。 +webhook 可以使用 `admissionReviewVersions` 字段定义它们接受的版本。 +API 服务器将尝试在其支持的列表中使用第一个版本。 +如果 API 服务器不支持此列表中指定的任何版本,则此对象的验证将失败。 +如果 webhook 配置依然如此,则对 we​​bhook 的调用将失败并受到失败策略的控制。 + +示例 admission webhook 服务器置 `ClientAuth` 字段为 +[空](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/images/webhook/config.go#L47-L48), +默认为 `NoClientCert` 。这意味着 webhook 服务器不会验证客户端的身份,认为其是 apiservers。 +如果您需要双向 TLS 或其他方式来验证客户端,请参阅如何[验证 apiservers](#验证 apiservers)。 + + +### 部署 admission webhook 服务 + +e2e 测试中的 webhook 服务器部署在 Kubernetes 集群中,通过 [deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1beta1-apps)。 +该测试还创建了 [service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) 作为 webhook 服务器的前端。 +参见[代码](https://github.com/kubernetes/kubernetes/blob/v1.13.0/test/e2e/apimachinery/webhook.go#L227)。 + +您还可以在集群外部署 Webhook, +这需要相应地更新 [webhook 客户端配置](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L247)。 + + +### 动态配置 admission webhook + +您可以通过 +[ValidatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L84) +或 +[MutatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L114) +动态配置哪些资源通过哪些 admission webhook + +以下是 `validatingWebhookConfiguration` 的示例,Mutating Webhook Configuration 类似。 + +```yaml +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: ValidatingWebhookConfiguration +metadata: + name: +webhooks: +- name: + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + scope: "Namespaced" + clientConfig: + service: + namespace: + name: + caBundle: + admissionReviewVersions: + - v1beta1 + timeoutSeconds: 1 +``` + + +scope 字段指定是否只有集群范围的资源(“Cluster”)或命名空间范围的资源(“Namespaced”)才匹配此规则。 “*” 表示没有范围限制。 + +{{< note >}} +使用`clientConfig.service`时,服务器证书必须对`..svc`有效。 +{{< /note >}} + +{{< note >}} +webhook 调用的默认超时为 30 秒,但从 kubernetes 1.14 开始,您可以设置超时,并鼓励对 webhook 使用非常小的超时时间。 +如果 webhook 调用超时,则根据 webhook 的失败策略处理请求。 +{{< /note >}} + +当一个 apiserver 收到一个与 `rules` 之一匹配的请求时,apiserver 会向 `clientConfig` 中指定的 webhook 发送一个 `admissionReview` 请求。 + +创建 webhook 配置后,系统将花费几秒钟来完成新配置的生效。 + + +### 验证 apiservers + +如果您的 webhooks 需要身份验证,您可以将 apiservers 配置为使用基本身份验证,不记名令牌或证书来对 webhook 进行身份验证。 +完成配置有三个步骤。 + +* 启动apiserver时,通过 `--admission-control-config-file` 参数指定许可控制配置文件的位置。 + +* 在准入控制配置文件中,指定 MutatingAdmissionWebhook 控制器和 ValidatingAdmissionWebhook 控制器应该读取凭据的位置。 +凭证存储在 kubeConfig 文件中(是​​的,与 kubectl 使用的模式相同),因此字段名称为`kubeConfigFile`。 +以下是一个示例准入控制配置文件: + +```yaml +apiVersion: apiserver.k8s.io/v1alpha1 +kind: AdmissionConfiguration +plugins: +- name: ValidatingAdmissionWebhook + configuration: + apiVersion: apiserver.config.k8s.io/v1alpha1 + kind: WebhookAdmission + kubeConfigFile: +- name: MutatingAdmissionWebhook + configuration: + apiVersion: apiserver.config.k8s.io/v1alpha1 + kind: WebhookAdmission + kubeConfigFile: +``` + + +`admissionConfiguration` 的 shcema 在 +[这里](https://github.com/kubernetes/kubernetes/blob/v1.13.0/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go#L27). + +* 在 kubeConfig 文件中,提供凭据: + +```yaml +apiVersion: v1 +kind: Config +users: +# DNS name of webhook service, i.e., ..svc, or the URL +# of the webhook server. +- name: 'webhook1.ns1.svc' + user: + client-certificate-data: + client-key-data: +# The `name` supports using * to wildmatch prefixing segments. +- name: '*.webhook-company.org' + user: + password: + username: +# '*' is the default match. +- name: '*' + user: + token: +``` + + +当然,您需要设置 webhook 服务器来处理这些身份验证。 +{{% /capture %}} diff --git a/content/zh/docs/reference/access-authn-authz/node.md b/content/zh/docs/reference/access-authn-authz/node.md new file mode 100644 index 0000000000000..255efffdc4286 --- /dev/null +++ b/content/zh/docs/reference/access-authn-authz/node.md @@ -0,0 +1,201 @@ +--- +title: 使用 Node 鉴权 +content_template: templates/concept +weight: 90 +--- + + +{{% capture overview %}} +节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求进行鉴权。 + +{{% /capture %}} + +{{% capture body %}} +## 概述 + + +节点鉴权器允许 kubelet 执行 API 操作。包括: + + +读取操作: + + +* services +* endpoints +* nodes +* pods +* secrets、configmaps、以及绑定到 kubelet 的节点的 pod 的持久卷申领和持久卷 + + +写入操作: + + +* 节点和节点状态(启用 `NodeRestriction` 准入插件以限制 kubelet 只能修改自己的节点) +* Pod 和 Pod 状态 (启用 `NodeRestriction` 准入插件以限制 kubelet 只能修改绑定到自身的 Pod) +* 事件 + + +鉴权相关操作: + + +* 对于基于 TLS 的启动引导过程时使用的 certificationsigningrequests API 的读/写权限 +* 为委派的身份验证/授权检查创建 tokenreviews 和 subjectaccessreviews 的能力 + + +在将来的版本中,节点鉴权器可能会添加或删除权限,以确保 kubelet 具有正确操作所需的最小权限集。 + + +为了获得节点鉴权器的授权,kubelet 必须使用一个凭证以表示它在 `system:nodes` 组中,用户名为 `system:node:`。 +上述的组名和用户名格式要与 [kubelet TLS 启动引导](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)过程中为每个 kubelet 创建的标识相匹配。 + + +要启用节点授权器,请使用 `--authorization-mode = Node` 启动 apiserver。 + + +要限制 kubelet 具有写入权限的 API 对象,请使用 `--enable-admission-plugins=...,NodeRestriction,...` 启动 apiserver,从而启用 [NodeRestriction](/docs/reference/access-authn-authz/admission-controllers#NodeRestriction) 准入插件。 + + +## 迁移考虑因素 + + +### 在 `system:nodes` 组之外的 Kubelet + + +`system:nodes` 组之外的 kubelet 不会被 `Node` 鉴权模式授权,并且需要继续通过当前授权它们的机制来授权。 +节点准入插件不会限制来自这些 kubelet 的请求。 + + +### 具有无差别用户名的 Kubelet + + +在一些部署中,kubelet 具有 `system:nodes` 组的凭证,但是无法给出它们所关联的节点的标识,因为它们没有 `system:node:...` 格式的用户名。 +这些 kubelet 不会被 `Node` 授权模式授权,并且需要继续通过当前授权它们的任何机制来授权。 + + +因为默认的节点标识符实现不会把它当作节点身份标识,`NodeRestriction` 准入插件会忽略来自这些 kubelet 的请求。 + + +### 相对于以前使用 RBAC 的版本的更新 + + +升级的 1.7 之前的使用 [RBAC](/docs/reference/access-authn-authz/rbac/) 的集群将继续按原样运行,因为 `system:nodes` 组绑定已经存在。 + + +如果集群管理员希望开始使用 `Node` 鉴权器和 `NodeRestriction` 准入插件来限制节点对 API 的访问,这一需求可以通过下列操作来完成且不会影响已部署的应用: + + +1. 启用 `Node` 鉴权模式 (`--authorization-mode=Node,RBAC`) 和 `NodeRestriction` 准入插件 +2. 确保所有 kubelet 的凭据符合组/用户名要求 +3. 审核 apiserver 日志以确保 `Node` 鉴权器不会拒绝来自 kubelet 的请求(日志中没有持续的 `NODE DENY` 消息) +4. 删除 `system:node` 集群角色绑定 + + +### RBAC 节点权限 + + +在 1.6 版本中,当使用 [RBAC 鉴权模式](/docs/reference/access-authn-authz/rbac/) 时,`system:nodes` 集群角色会被自动绑定到 `system:node` 组。 + + +在 1.7 版本中,不再推荐将 `system:nodes` 组自动绑定到 `system:node` 角色,因为节点鉴权器通过对 secret 和 configmap 访问的额外限制完成了相同的任务。 +如果同时启用了 `Node` 和 `RBAC` 授权模式,1.7 版本则不会创建 `system:nodes` 组到 `system:node` 角色的自动绑定。 + + +在 1.8 版本中,绑定将根本不会被创建。 + + +使用 RBAC 时,将继续创建 `system:node` 集群角色,以便与将其他用户或组绑定到该角色的部署方法兼容。 + +{{% /capture %}} diff --git a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md index bf3e0783f908b..65d9aeeb532fb 100644 --- a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md +++ b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md @@ -4,58 +4,58 @@ approvers: - davidopp - lavalamp - liggitt -title: 管理Service Accounts +title: 管理 Service Accounts --- -*这是一篇针对service accounts(服务账户)的集群管理员指南。 它呈现了 [User Guide to Service Accounts](/docs/user-guide/service-accounts)中的信息。* +*这是一篇针对 service accounts(服务账户)的集群管理员指南。 它呈现了 [User Guide to Service Accounts](/docs/user-guide/service-accounts) 中的信息。* -*对授权和用户账户的支持已在规划中,当前并不完备,为了更好地描述service accounts,有时这些不完善的特性也会被提及。* +*对授权和用户账户的支持已在规划中,当前并不完备,为了更好地描述 service accounts,有时这些不完善的特性也会被提及。* ## 用户账户与服务账户 Kubernetes 区分用户账户和服务账户的概念主要基于以下原因: - - 用户账户是针对人而言的。 服务账户是针对运行在pod中的进程而言的。 - - 用户账户是全局性的。 其名称在集群各namespace中都是全局唯一的,未来的用户资源不会做namespace隔离, - 服务账户是namespace隔离的。 - - 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 (即权限最小化原则)。 + - 用户账户是针对人而言的。 服务账户是针对运行在 pod 中的进程而言的。 + - 用户账户是全局性的。 其名称在集群各 namespace 中都是全局唯一的,未来的用户资源不会做 namespace 隔离, + 服务账户是 namespace 隔离的。 + - 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 ( 即权限最小化原则 )。 - 对人员和服务账户审计所考虑的因素可能不同。 - - 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有namespace级别的名称,这种配置是很轻量的。 + - 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有 namespace 级别的名称,这种配置是很轻量的。 ## 服务账户的自动化 -三个独立组件协作完成服务账户相关的自动化: +三个独立组件协作完成服务账户相关的自动化 : - 服务账户准入控制器(Service account admission controller) - - Token控制器(Token controller) + - Token 控制器(Token controller) - 服务账户控制器(Service account controller) ### 服务账户准入控制器 -对pod的改动通过一个被称为[Admission Controller](/docs/admin/admission-controllers)的插件来实现。它是apiserver的一部分。 -当pod被创建或更新时,它会同步地修改pod。 当该插件处于激活状态(在大多数发行版中都是默认的),当pod被创建或更新时它会进行以下动作: +对 pod 的改动通过一个被称为 [Admission Controller](/docs/admin/admission-controllers) 的插件来实现。它是 apiserver 的一部分。 +当 pod 被创建或更新时,它会同步地修改 pod。 当该插件处于激活状态 ( 在大多数发行版中都是默认的 ),当 pod 被创建或更新时它会进行以下动作: - 1. 如果该pod没有 `ServiceAccount` 设置,将其 `ServiceAccount` 设为 `default`。 - 2. 保证pod所关联的 `ServiceAccount` 存在,否则拒绝该pod。 - 4. 如果pod不包含 `ImagePullSecrets`设置,那么 将 `ServiceAccount`中的`ImagePullSecrets` 信息添加到pod中。 - 5. 将一个包含用于API访问的token的 `volume` 添加到pod中。 - 6. 将挂载于 `/var/run/secrets/kubernetes.io/serviceaccount` 的 `volumeSource`添加到pod下的每个容器中。 + 1. 如果该 pod 没有 `ServiceAccount` 设置,将其 `ServiceAccount` 设为 `default`。 + 2. 保证 pod 所关联的 `ServiceAccount` 存在,否则拒绝该 pod。 + 4. 如果 pod 不包含 `ImagePullSecrets` 设置,那么 将 `ServiceAccount` 中的 `ImagePullSecrets` 信息添加到 pod 中。 + 5. 将一个包含用于 API 访问的 token 的 `volume` 添加到 pod 中。 + 6. 将挂载于 `/var/run/secrets/kubernetes.io/serviceaccount` 的 `volumeSource` 添加到 pod 下的每个容器中。 -### Token管理器 +### Token 管理器 -Token管理器是controller-manager的一部分。 以异步的形式工作: +Token 管理器是 controller-manager 的一部分。 以异步的形式工作: -- 检测服务账户的创建,并且创建相应的Secret以支持API访问。 -- 检测服务账户的删除,并且删除所有相应的服务账户Token Secret。 -- 检测Secret的增加,保证相应的服务账户存在,如有需要,为Secret增加token。 -- 检测Secret的删除,如有需要,从相应的服务账户中移除引用。 +- 检测服务账户的创建,并且创建相应的 Secret 以支持 API 访问。 +- 检测服务账户的删除,并且删除所有相应的服务账户 Token Secret。 +- 检测 Secret 的增加,保证相应的服务账户存在,如有需要,为 Secret 增加 token。 +- 检测 Secret 的删除,如有需要,从相应的服务账户中移除引用。 -你需要通过 `--service-account-private-key-file` 参数项传入一个服务账户私钥文件至Token管理器。 私钥用于为生成的服务账户token签名。 -同样地,你需要通过 `--service-account-key-file` 参数将对应的公钥传入kube-apiserver。 公钥用于认证过程中的token校验。 +你需要通过 `--service-account-private-key-file` 参数项传入一个服务账户私钥文件至 Token 管理器。 私钥用于为生成的服务账户 token 签名。 +同样地,你需要通过 `--service-account-key-file` 参数将对应的公钥传入 kube-apiserver。 公钥用于认证过程中的 token 校验。 #### 创建额外的 API tokens -控制器中有专门的循环来保证每个服务账户中都存在API token对应的Secret。 当需要为服务账户创建额外的API token时,创建一个类型为 `ServiceAccountToken` 的Secret,并在annotation中引用服务账户,控制器会生成token并更新: +控制器中有专门的循环来保证每个服务账户中都存在 API token 对应的 Secret。 当需要为服务账户创建额外的 API token 时,创建一个类型为 `ServiceAccountToken` 的 Secret,并在 annotation 中引用服务账户,控制器会生成 token 并更新 : secret.json: @@ -78,7 +78,7 @@ kubectl create -f ./secret.json kubectl describe secret mysecretname ``` -#### 删除/失效 服务账户token +#### 删除 / 失效 服务账户 token ```shell kubectl delete secret mysecretname diff --git a/content/zh/docs/reference/access-authn-authz/webhook.md b/content/zh/docs/reference/access-authn-authz/webhook.md index e80fed7dc297e..c82049f8d3587 100644 --- a/content/zh/docs/reference/access-authn-authz/webhook.md +++ b/content/zh/docs/reference/access-authn-authz/webhook.md @@ -29,10 +29,10 @@ WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通 clusters: - name: name-of-remote-authz-service cluster: - certificate-authority: /path/to/ca.pem # 对远程服务进行身份认证的CA。 + certificate-authority: /path/to/ca.pem # 对远程服务进行身份认证的 CA。 server: https://authz.example.com/authorize # 远程服务的查询 URL. 必须使用 'https'。 -# users 代表 API 服务器的 webhook 配置. +# users 代表 API 服务器的 webhook 配置 . users: - name: name-of-api-server user: @@ -55,7 +55,7 @@ contexts: 需要注意的是 webhook API 对象与其他 Kubernetes API 对象一样都同样都服从 [版本兼容规则](/docs/api/) 。 实施人员应该了解 beta 对象的更宽松的兼容性承诺,同时确认请求的 "apiVersion" 字段以确保能被正确地反序列化。 -此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组(`--runtime-config=authorization.k8s.io/v1beta1=true`)。 +此外,API 服务器还必须启用 `authorization.k8s.io/v1beta1` API 扩展组 (`--runtime-config=authorization.k8s.io/v1beta1=true`)。 一个请求内容的例子: diff --git a/content/zh/docs/reference/command-line-tools-reference/_index.md b/content/zh/docs/reference/command-line-tools-reference/_index.md index dcd66f2df9f96..7c2792e89403d 100644 --- a/content/zh/docs/reference/command-line-tools-reference/_index.md +++ b/content/zh/docs/reference/command-line-tools-reference/_index.md @@ -1,5 +1,13 @@ --- -title: 命令行工具 +title: 命令行工具参考 weight: 60 toc-hide: true --- + + diff --git a/content/zh/docs/reference/command-line-tools-reference/kube-apiserver.md b/content/zh/docs/reference/command-line-tools-reference/kube-apiserver.md index 53b9836812fdf..f24899755f83c 100644 --- a/content/zh/docs/reference/command-line-tools-reference/kube-apiserver.md +++ b/content/zh/docs/reference/command-line-tools-reference/kube-apiserver.md @@ -9,7 +9,7 @@ notitle: true ### 概要 -Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、 replicationcontrollers和其它 api 对象。API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。 +Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、 replicationcontrollers 和其它 api 对象。API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。 ``` kube-apiserver @@ -18,99 +18,99 @@ kube-apiserver ### 选项 ``` - --admission-control stringSlice 控制资源进入集群的准入控制插件的顺序列表。逗号分隔的NamespaceLifecycle列表。(默认值[AlwaysAdmit]) + --admission-control stringSlice 控制资源进入集群的准入控制插件的顺序列表。逗号分隔的 NamespaceLifecycle 列表。(默认值 [AlwaysAdmit]) --admission-control-config-file string 包含准入控制配置的文件。 - --advertise-address ip 向集群成员通知apiserver消息的IP地址。这个地址必须能够被集群中其他成员访问。如果IP地址为空,将会使用--bind-address,如果未指定--bind-address,将会使用主机的默认接口地址。 + --advertise-address ip 向集群成员通知 apiserver 消息的 IP 地址。这个地址必须能够被集群中其他成员访问。如果 IP 地址为空,将会使用 --bind-address,如果未指定 --bind-address,将会使用主机的默认接口地址。 - --allow-privileged 如果为true, 将允许特权容器. + --allow-privileged 如果为 true, 将允许特权容器。 - --anonymous-auth 启用到API server的安全端口的匿名请求。未被其他认证方法拒绝的请求被当做匿名请求。匿名请求的用户名为system:anonymous,用户组名为system:unauthenticated。(默认值true) + --anonymous-auth 启用到 API server 的安全端口的匿名请求。未被其他认证方法拒绝的请求被当做匿名请求。匿名请求的用户名为 system:anonymous,用户组名为 system:unauthenticated。(默认值 true) - --apiserver-count int 集群中运行的apiserver数量,必须为正数。(默认值1) + --apiserver-count int 集群中运行的 apiserver 数量,必须为正数。(默认值 1) --audit-log-maxage int 基于文件名中的时间戳,旧审计日志文件的最长保留天数。 - --audit-log-maxbackup int 旧审计日志文件的最大保留个数. + --audit-log-maxbackup int 旧审计日志文件的最大保留个数。 --audit-log-maxsize int 审计日志被轮转前的最大兆字节数。 - --audit-log-path string 如果设置该值,所有到apiserver的请求都将会被记录到这个文件。'-'表示记录到标准输出。 + --audit-log-path string 如果设置该值,所有到 apiserver 的请求都将会被记录到这个文件。'-' 表示记录到标准输出。 - --audit-policy-file string 定义审计策略配置的文件的路径。需要打开'AdvancedAuditing'特性开关。AdvancedAuditing需要一个配置来启用审计功能。 + --audit-policy-file string 定义审计策略配置的文件的路径。需要打开 'AdvancedAuditing' 特性开关。AdvancedAuditing 需要一个配置来启用审计功能。 - --audit-webhook-config-file string 一个具有kubeconfig格式文件的路径,该文件定义了审计的webhook配置。需要打开'AdvancedAuditing'特性开关。 + --audit-webhook-config-file string 一个具有 kubeconfig 格式文件的路径,该文件定义了审计的 webhook 配置。需要打开 'AdvancedAuditing' 特性开关。 - --audit-webhook-mode string 发送审计事件的策略。 Blocking模式表示正在发送事件时应该阻塞服务器的响应。 Batch模式使webhook异步缓存和发送事件。 Known模式为batch,blocking。 (默认值"batch") + --audit-webhook-mode string 发送审计事件的策略。 Blocking 模式表示正在发送事件时应该阻塞服务器的响应。 Batch 模式使 webhook 异步缓存和发送事件。 Known 模式为 batch,blocking。(默认值 "batch") - --authentication-token-webhook-cache-ttl duration 从webhook令牌认证者获取的响应的缓存时长。(默认值2m0s) + --authentication-token-webhook-cache-ttl duration 从 webhook 令牌认证者获取的响应的缓存时长。( 默认值 2m0s) - --authentication-token-webhook-config-file string 包含webhook配置的文件,用于令牌认证,具有kubeconfig格式。API server将查询远程服务来决定对bearer令牌的认证。 + --authentication-token-webhook-config-file string 包含 webhook 配置的文件,用于令牌认证,具有 kubeconfig 格式。API server 将查询远程服务来决定对 bearer 令牌的认证。 - --authorization-mode string 在安全端口上进行权限验证的插件的顺序列表。以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值"AlwaysAllow") + --authorization-mode string 在安全端口上进行权限验证的插件的顺序列表。以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值 "AlwaysAllow") - --authorization-policy-file string 包含权限验证策略的csv文件,和--authorization-mode=ABAC一起使用,作用在安全端口上。 + --authorization-policy-file string 包含权限验证策略的 csv 文件,和 --authorization-mode=ABAC 一起使用,作用在安全端口上。 - --authorization-webhook-cache-authorized-ttl duration 从webhook授权者获得的'authorized'响应的缓存时长。(默认值5m0s) + --authorization-webhook-cache-authorized-ttl duration 从 webhook 授权者获得的 'authorized' 响应的缓存时长。(默认值 5m0s) - --authorization-webhook-cache-unauthorized-ttl duration 从webhook授权者获得的'unauthorized'响应的缓存时长。(默认值30s) + --authorization-webhook-cache-unauthorized-ttl duration 从 webhook 授权者获得的 'unauthorized' 响应的缓存时长。(默认值 30s) - --authorization-webhook-config-file string 包含webhook配置的kubeconfig格式文件,和--authorization-mode=Webhook一起使用。API server将查询远程服务来决定对API server安全端口的访问。 + --authorization-webhook-config-file string 包含 webhook 配置的 kubeconfig 格式文件,和 --authorization-mode=Webhook 一起使用。API server 将查询远程服务来决定对 API server 安全端口的访问。 - --azure-container-registry-config string 包含Azure容器注册表配置信息的文件的路径。 + --azure-container-registry-config string 包含 Azure 容器注册表配置信息的文件的路径。 - --basic-auth-file string 如果设置该值,这个文件将会被用于准许通过http基本认证到API server安全端口的请求。 + --basic-auth-file string 如果设置该值,这个文件将会被用于准许通过 http 基本认证到 API server 安全端口的请求。 - --bind-address ip 监听--seure-port的IP地址。被关联的接口必须能够被集群其它节点和CLI/web客户端访问。如果为空,则将使用所有接口(0.0.0.0)。(默认值0.0.0.0) + --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") + --cert-dir string 存放 TLS 证书的目录。如果提供了 --tls-cert-file 和 --tls-private-key-file 选项,该标志将被忽略。(默认值 "/var/run/kubernetes") - --client-ca-file string 如果设置此标志,对于任何请求,如果存包含client-ca-file中的authorities签名的客户端证书,将会使用客户端证书中的CommonName对应的身份进行认证。 + --client-ca-file string 如果设置此标志,对于任何请求,如果存包含 client-ca-file 中的 authorities 签名的客户端证书,将会使用客户端证书中的 CommonName 对应的身份进行认证。 - --cloud-config string 云服务提供商配置文件路径。空字符串表示无配置文件. + --cloud-config string 云服务提供商配置文件路径。空字符串表示无配置文件 . --cloud-provider string 云服务提供商,空字符串表示无提供商。 - --contention-profiling 如果已经启用profiling,则启用锁竞争profiling。 + --contention-profiling 如果已经启用 profiling,则启用锁竞争 profiling。 - --cors-allowed-origins stringSlice CORS的域列表,以逗号分隔。合法的域可以是一个匹配子域名的正则表达式。如果这个列表为空则不会启用CORS. + --cors-allowed-origins stringSlice CORS 的域列表,以逗号分隔。合法的域可以是一个匹配子域名的正则表达式。如果这个列表为空则不会启用 CORS. - --delete-collection-workers int 用于DeleteCollection调用的工作者数量。这被用于加速namespace的清理。(默认值1) + --delete-collection-workers int 用于 DeleteCollection 调用的工作者数量。这被用于加速 namespace 的清理。( 默认值 1) - --deserialization-cache-size int 在内存中缓存的反序列化json对象的数量。 + --deserialization-cache-size int 在内存中缓存的反序列化 json 对象的数量。 - --enable-aggregator-routing 打开到endpoints IP的aggregator路由请求,替换cluster IP。 + --enable-aggregator-routing 打开到 endpoints IP 的 aggregator 路由请求,替换 cluster IP。 - --enable-garbage-collector 启用通用垃圾回收器. 必须与kube-controller-manager对应的标志保持同步。 (默认值true) + --enable-garbage-collector 启用通用垃圾回收器 . 必须与 kube-controller-manager 对应的标志保持同步。 (默认值 true) - --enable-logs-handler 如果为true,则为apiserver日志功能安装一个/logs处理器。(默认值true) + --enable-logs-handler 如果为 true,则为 apiserver 日志功能安装一个 /logs 处理器。(默认值 true) - --enable-swagger-ui 在apiserver的/swagger-ui路径启用swagger ui。 + --enable-swagger-ui 在 apiserver 的 /swagger-ui 路径启用 swagger ui。 - --etcd-cafile string 用于保护etcd通信的SSL CA文件。 + --etcd-cafile string 用于保护 etcd 通信的 SSL CA 文件。 - --etcd-certfile string 用于保护etcd通信的的SSL证书文件。 + --etcd-certfile string 用于保护 etcd 通信的的 SSL 证书文件。 - --etcd-keyfile string 用于保护etcd通信的SSL密钥文件. + --etcd-keyfile string 用于保护 etcd 通信的 SSL 密钥文件 . - --etcd-prefix string 附加到所有etcd中资源路径的前缀。 (默认值"/registry") + --etcd-prefix string 附加到所有 etcd 中资源路径的前缀。 (默认值 "/registry") - --etcd-quorum-read 如果为true, 启用quorum读。 + --etcd-quorum-read 如果为 true, 启用 quorum 读。 - --etcd-servers stringSlice 连接的etcd服务器列表,形式为(scheme://ip:port),使用逗号分隔。 + --etcd-servers stringSlice 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔。 - --etcd-servers-overrides stringSlice 针对单个资源的etcd服务器覆盖配置, 以逗号分隔。 单个配置覆盖格式为: group/resource#servers, 其中servers形式为http://ip:port, 以分号分隔。 + --etcd-servers-overrides stringSlice 针对单个资源的 etcd 服务器覆盖配置 , 以逗号分隔。 单个配置覆盖格式为 : group/resource#servers, 其中 servers 形式为 http://ip:port, 以分号分隔。 - --event-ttl duration 事件驻留时间。(默认值1h0m0s) + --event-ttl duration 事件驻留时间。(默认值 1h0m0s) - --enable-bootstrap-token-auth 启用此选项以允许'kube-system'命名空间中的'bootstrap.kubernetes.io/token'类型密钥可以被用于TLS的启动认证。 + --enable-bootstrap-token-auth 启用此选项以允许 'kube-system' 命名空间中的 'bootstrap.kubernetes.io/token' 类型密钥可以被用于 TLS 的启动认证。 - --experimental-encryption-provider-config string 包含加密提供程序的配置的文件,该加密提供程序被用于在etcd中保存密钥。 + --experimental-encryption-provider-config string 包含加密提供程序的配置的文件,该加密提供程序被用于在 etcd 中保存密钥。 - --external-hostname string 为此master生成外部URL时使用的主机名(例如Swagger API文档)。 + --external-hostname string 为此 master 生成外部 URL 时使用的主机名 ( 例如 Swagger API 文档 )。 - --feature-gates mapStringBool 一个描述alpha/experimental特性开关的键值对列表。 选项包括: + --feature-gates mapStringBool 一个描述 alpha/experimental 特性开关的键值对列表。 选项包括 : Accelerators=true|false (ALPHA - default=false) AdvancedAuditing=true|false (ALPHA - default=false) AffinityInAnnotations=true|false (ALPHA - default=false) @@ -128,102 +128,102 @@ 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密钥。 + --google-json-key string 用于认证的 Google Cloud Platform 服务账号的 JSON 密钥。 - --insecure-allow-any-token username/group1,group2 如果设置该值, 你的服务将处于非安全状态。任何令牌都将会被允许,并将从令牌中把用户信息解析成为username/group1,group2。 + --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-bind-address ip 用于监听 --insecure-port 的 IP 地址 ( 设置成 0.0.0.0 表示监听所有接口 )。(默认值 127.0.0.1) - --insecure-port int 用于监听不安全和为认证访问的端口。这个配置假设你已经设置了防火墙规则,使得这个端口不能从集群外访问。对集群的公共地址的443端口的访问将被代理到这个端口。默认设置中使用nginx实现。(默认值8080) + --insecure-port int 用于监听不安全和为认证访问的端口。这个配置假设你已经设置了防火墙规则,使得这个端口不能从集群外访问。对集群的公共地址的 443 端口的访问将被代理到这个端口。默认设置中使用 nginx 实现。(默认值 8080) - --kubelet-certificate-authority string 证书authority的文件路径。 + --kubelet-certificate-authority string 证书 authority 的文件路径。 - --kubelet-client-certificate string 用于TLS的客户端证书文件路径。 + --kubelet-client-certificate string 用于 TLS 的客户端证书文件路径。 - --kubelet-client-key string 用于TLS的客户端证书密钥文件路径. + --kubelet-client-key string 用于 TLS 的客户端证书密钥文件路径 . - --kubelet-https 为kubelet启用https。 (默认值true) + --kubelet-https 为 kubelet 启用 https。 (默认值 true) - --kubelet-preferred-address-types stringSlice 用于kubelet连接的首选NodeAddressTypes列表。 (默认值[Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP]) + --kubelet-preferred-address-types stringSlice 用于 kubelet 连接的首选 NodeAddressTypes 列表。 ( 默认值[Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP]) - --kubelet-read-only-port uint 已废弃: kubelet端口. (默认值10255) + --kubelet-read-only-port uint 已废弃 : kubelet 端口 . (默认值 10255) - --kubelet-timeout duration kubelet操作超时时间。(默认值 + --kubelet-timeout duration kubelet 操作超时时间。(默认值 5s) - --kubernetes-service-node-port int 如果不为0,Kubernetes master服务(用于创建/管理apiserver)将会使用NodePort类型,并将这个值作为端口号。如果为0,Kubernetes master服务将会使用ClusterIP类型。 + --kubernetes-service-node-port int 如果不为 0,Kubernetes master 服务(用于创建 / 管理 apiserver)将会使用 NodePort 类型,并将这个值作为端口号。如果为 0,Kubernetes master 服务将会使用 ClusterIP 类型。 - --master-service-namespace string 已废弃: 注入到pod中的kubernetes master服务的命名空间。(默认值"default") + --master-service-namespace string 已废弃 : 注入到 pod 中的 kubernetes master 服务的命名空间。(默认值 "default") - --max-connection-bytes-per-sec int 如果不为0,每个用户连接将会被限速为该值(bytes/sec)。当前只应用于长时间运行的请求。 + --max-connection-bytes-per-sec int 如果不为 0,每个用户连接将会被限速为该值(bytes/sec)。当前只应用于长时间运行的请求。 - --max-mutating-requests-inflight int 在给定时间内进行中可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值200) + --max-mutating-requests-inflight int 在给定时间内进行中可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0 值表示没有限制。(默认值 200) - --max-requests-inflight int 在给定时间内进行中不可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值400) + --max-requests-inflight int 在给定时间内进行中不可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0 值表示没有限制。(默认值 400) - --min-request-timeout int 一个可选字段,表示一个handler在一个请求超时前,必须保持它处于打开状态的最小秒数。当前只对监听请求handler有效,它基于这个值选择一个随机数作为连接超时值,以达到分散负载的目的(默认值1800)。 + --min-request-timeout int 一个可选字段,表示一个 handler 在一个请求超时前,必须保持它处于打开状态的最小秒数。当前只对监听请求 handler 有效,它基于这个值选择一个随机数作为连接超时值,以达到分散负载的目的(默认值 1800)。 - --oidc-ca-file string 如果设置该值,将会使用oidc-ca-file中的任意一个authority对OpenID服务的证书进行验证,否则将会使用主机的根CA对其进行验证。 + --oidc-ca-file string 如果设置该值,将会使用 oidc-ca-file 中的任意一个 authority 对 OpenID 服务的证书进行验证,否则将会使用主机的根 CA 对其进行验证。 - --oidc-client-id string 使用OpenID连接的客户端的ID,如果设置了oidc-issuer-url,则必须设置这个值。 + --oidc-client-id string 使用 OpenID 连接的客户端的 ID,如果设置了 oidc-issuer-url,则必须设置这个值。 - --oidc-groups-claim string 如果提供该值,这个自定义OpenID连接名将指定给特定的用户组。该声明值需要是一个字符串或字符串数组。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 + --oidc-groups-claim string 如果提供该值,这个自定义 OpenID 连接名将指定给特定的用户组。该声明值需要是一个字符串或字符串数组。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 - --oidc-issuer-url string OpenID颁发者URL,只接受HTTPS方案。如果设置该值,它将被用于验证OIDC JSON Web Token(JWT)。 + --oidc-issuer-url string OpenID 颁发者 URL,只接受 HTTPS 方案。如果设置该值,它将被用于验证 OIDC JSON Web Token(JWT)。 - --oidc-username-claim string 用作用户名的OpenID声明值。注意,不保证除默认 ('sub')外的其他声明值的唯一性和不变性。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 + --oidc-username-claim string 用作用户名的 OpenID 声明值。注意,不保证除默认 ('sub') 外的其他声明值的唯一性和不变性。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 - --profiling 在web接口host:port/debug/pprof/上启用profiling。(默认值true) + --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-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准入控制插件的请求。 + --proxy-client-key-file string 当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书密钥。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求。 - --repair-malformed-updates 如果为true,服务将会尽力修复更新请求以通过验证,例如:将更新请求UID的当前值设置为空。在我们修复了所有发送错误格式请求的客户端后,可以关闭这个标志。 + --repair-malformed-updates 如果为 true,服务将会尽力修复更新请求以通过验证,例如:将更新请求 UID 的当前值设置为空。在我们修复了所有发送错误格式请求的客户端后,可以关闭这个标志。 - --requestheader-allowed-names stringSlice 使用--requestheader-username-headers指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过--requestheader-client-ca-file中authorities验证的客户端证书都是被允许的。 + --requestheader-allowed-names stringSlice 使用 --requestheader-username-headers 指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过 --requestheader-client-ca-file 中 authorities 验证的客户端证书都是被允许的。 - --requestheader-client-ca-file string 在信任请求头中以--requestheader-username-headers指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。 + --requestheader-client-ca-file string 在信任请求头中以 --requestheader-username-headers 指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。 - --requestheader-extra-headers-prefix stringSlice 用于检查的请求头的前缀列表。建议使用X-Remote-Extra-。 + --requestheader-extra-headers-prefix stringSlice 用于检查的请求头的前缀列表。建议使用 X-Remote-Extra-。 - --requestheader-group-headers stringSlice 用于检查群组的请求头列表。建议使用X-Remote-Group. + --requestheader-group-headers stringSlice 用于检查群组的请求头列表。建议使用 X-Remote-Group. - --requestheader-username-headers stringSlice 用于检查用户名的请求头列表。建议使用X-Remote-User。 + --requestheader-username-headers stringSlice 用于检查用户名的请求头列表。建议使用 X-Remote-User。 - --runtime-config mapStringString 传递给apiserver用于描述运行时配置的键值对集合。 apis/键可以被用来打开/关闭特定的api版本。apis//键被用来打开/关闭特定的资源. api/all和api/legacy键分别用于控制所有的和遗留的api版本. + --runtime-config mapStringString 传递给 apiserver 用于描述运行时配置的键值对集合。 apis/ 键可以被用来打开 / 关闭特定的 api 版本。apis// 键被用来打开 / 关闭特定的资源 . api/all 和 api/legacy 键分别用于控制所有的和遗留的 api 版本 . - --secure-port int 用于监听具有认证授权功能的HTTPS协议的端口。如果为0,则不会监听HTTPS协议。 (默认值6443) + --secure-port int 用于监听具有认证授权功能的 HTTPS 协议的端口。如果为 0,则不会监听 HTTPS 协议。 (默认值 6443) - --service-account-key-file stringArray 包含PEM加密的x509 RSA或ECDSA私钥或公钥的文件,用于验证ServiceAccount令牌。如果设置该值,--tls-private-key-file将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。 + --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范围产生重叠。 + --service-cluster-ip-range ipNet CIDR 表示的 IP 范围,服务的 cluster ip 将从中分配。 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠。 - --ssh-keyfile string 如果不为空,在使用安全的SSH代理访问节点时,将这个文件作为用户密钥文件。 + --ssh-keyfile string 如果不为空,在使用安全的 SSH 代理访问节点时,将这个文件作为用户密钥文件。 - --storage-backend string 持久化存储后端。 选项为: 'etcd3' (默认), 'etcd2'. + --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") + --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(用于配置缓存大小等)。 + --target-ram-mb int apiserver 内存限制,单位为 MB( 用于配置缓存大小等 )。 - --tls-ca-file string 如果设置该值,这个证书authority将会被用于从Admission Controllers过来的安全访问。它必须是一个PEM加密的合法CA捆绑包。此外, 该证书authority可以被添加到以--tls-cert-file提供的证书文件中. + --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-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-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". (默认值[]) + --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服务的安全端口。 + --token-auth-file string 如果设置该值,这个文件将被用于通过令牌认证来保护 API 服务的安全端口。 --version version[=true] 打印版本信息并退出。 - --watch-cache 启用apiserver的监视缓存。(默认值true) + --watch-cache 启用 apiserver 的监视缓存。(默认值 true) - --watch-cache-sizes stringSlice 每种资源(pods, nodes等)的监视缓存大小列表,以逗号分隔。每个缓存配置的形式为:resource#size,size是一个数字。在watch-cache启用时生效。 + --watch-cache-sizes stringSlice 每种资源(pods, nodes 等)的监视缓存大小列表,以逗号分隔。每个缓存配置的形式为:resource#size,size 是一个数字。在 watch-cache 启用时生效。 ``` ###### Auto generated by spf13/cobra on 11-Jul-2017 diff --git a/content/zh/docs/reference/command-line-tools-reference/kube-controller-manager.md b/content/zh/docs/reference/command-line-tools-reference/kube-controller-manager.md new file mode 100644 index 0000000000000..448f0de7aef37 --- /dev/null +++ b/content/zh/docs/reference/command-line-tools-reference/kube-controller-manager.md @@ -0,0 +1,818 @@ +--- +title: kube-controller-manager +notitle: true +--- + +## kube-controller-manager + + + +### 概述 + + + +Kubernetes 控制器管理器是一个守护进程,嵌入了 Kubernetes 附带的核心控制循环。 在机器人和自动化的应用中,控制回路是一个永不休止的循环,用于调节系统状态。 在 Kubernetes 中,控制器是一个控制循环,它通过 apiserver 监视集群的共享状态,并尝试进行更改以将当前状态转为所需状态。现今,Kubernetes 自带的控制器包括副本控制器,节点控制器,命名空间控制器和serviceaccounts 控制器。 + +``` +kube-controller-manager [flags] +``` + + +### 选项 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
--allocate-node-cidrs
Should CIDRs for Pods be allocated and set on the cloud provider.
--alsologtostderr
log to standard error as well as files
--attach-detach-reconcile-sync-period duration     Default: 1m0s
The reconciler sync wait time between volume attach detach. This duration must be larger than one second, and increasing this value from the default may allow for volumes to be mismatched with pods.
--authentication-kubeconfig string
kubeconfig file pointing at the 'core' kubernetes server with enough rights to create tokenaccessreviews.authentication.k8s.io. This is optional. If empty, all token requests are considered to be anonymous and no client CA is looked up in the cluster.
--authentication-skip-lookup
If false, the authentication-kubeconfig will be used to lookup missing authentication configuration from the cluster.
--authentication-token-webhook-cache-ttl duration     Default: 10s
The duration to cache responses from the webhook token authenticator.
--authentication-tolerate-lookup-failure
If true, failures to look up missing authentication configuration from the cluster are not considered fatal. Note that this can result in authentication that treats all requests as anonymous.
--authorization-always-allow-paths stringSlice     Default: [/healthz]
A list of HTTP paths to skip during authorization, i.e. these are authorized without contacting the 'core' kubernetes server.
--authorization-kubeconfig string
kubeconfig file pointing at the 'core' kubernetes server with enough rights to create subjectaccessreviews.authorization.k8s.io. This is optional. If empty, all requests not skipped by authorization are forbidden.
--authorization-webhook-cache-authorized-ttl duration     Default: 10s
The duration to cache 'authorized' responses from the webhook authorizer.
--authorization-webhook-cache-unauthorized-ttl duration     Default: 10s
The duration to cache 'unauthorized' responses from the webhook authorizer.
--azure-container-registry-config string
Path to the file containing Azure container registry configuration information.
--bind-address ip     Default: 0.0.0.0
The IP address on which to listen for the --secure-port port. The associated interface(s) must be reachable by the rest of the cluster, and by CLI/web clients. If blank, all interfaces will be used (0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).
--cert-dir string
The directory where the TLS certs are located. If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.
--cidr-allocator-type string     Default: "RangeAllocator"
Type of CIDR allocator to use
--client-ca-file string
If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file is authenticated with an identity corresponding to the CommonName of the client certificate.
--cloud-config string
The path to the cloud provider configuration file. Empty string for no configuration file.
--cloud-provider string
The provider for cloud services. Empty string for no provider.
--cluster-cidr string
CIDR Range for Pods in cluster. Requires --allocate-node-cidrs to be true
--cluster-name string     Default: "kubernetes"
The instance prefix for the cluster.
--cluster-signing-cert-file string     Default: "/etc/kubernetes/ca/ca.pem"
Filename containing a PEM-encoded X509 CA certificate used to issue cluster-scoped certificates
--cluster-signing-key-file string     Default: "/etc/kubernetes/ca/ca.key"
Filename containing a PEM-encoded RSA or ECDSA private key used to sign cluster-scoped certificates
--concurrent-deployment-syncs int32     Default: 5
The number of deployment objects that are allowed to sync concurrently. Larger number = more responsive deployments, but more CPU (and network) load
--concurrent-endpoint-syncs int32     Default: 5
The number of endpoint syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load
--concurrent-gc-syncs int32     Default: 20
The number of garbage collector workers that are allowed to sync concurrently.
--concurrent-namespace-syncs int32     Default: 10
The number of namespace objects that are allowed to sync concurrently. Larger number = more responsive namespace termination, but more CPU (and network) load
--concurrent-replicaset-syncs int32     Default: 5
The number of replica sets that are allowed to sync concurrently. Larger number = more responsive replica management, but more CPU (and network) load
--concurrent-resource-quota-syncs int32     Default: 5
The number of resource quotas that are allowed to sync concurrently. Larger number = more responsive quota management, but more CPU (and network) load
--concurrent-service-syncs int32     Default: 1
The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load
--concurrent-serviceaccount-token-syncs int32     Default: 5
The number of service account token objects that are allowed to sync concurrently. Larger number = more responsive token generation, but more CPU (and network) load
--concurrent-ttl-after-finished-syncs int32     Default: 5
The number of TTL-after-finished controller workers that are allowed to sync concurrently.
--concurrent_rc_syncs int32     Default: 5
The number of replication controllers that are allowed to sync concurrently. Larger number = more responsive replica management, but more CPU (and network) load
--configure-cloud-routes     Default: true
Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.
--contention-profiling
Enable lock contention profiling, if profiling is enabled
--controller-start-interval duration
Interval between starting controller managers.
--controllers stringSlice     Default: [*]
A list of controllers to enable. '*' enables all on-by-default controllers, 'foo' enables the controller named 'foo', '-foo' disables the controller named 'foo'.
All controllers: attachdetach, bootstrapsigner, cloud-node-lifecycle, clusterrole-aggregation, cronjob, csrapproving, csrcleaner, csrsigning, daemonset, deployment, disruption, endpoint, garbagecollector, horizontalpodautoscaling, job, namespace, nodeipam, nodelifecycle, persistentvolume-binder, persistentvolume-expander, podgc, pv-protection, pvc-protection, replicaset, replicationcontroller, resourcequota, root-ca-cert-publisher, route, service, serviceaccount, serviceaccount-token, statefulset, tokencleaner, ttl, ttl-after-finished
Disabled-by-default controllers: bootstrapsigner, tokencleaner
--deployment-controller-sync-period duration     Default: 30s
Period for syncing the deployments.
--disable-attach-detach-reconcile-sync
Disable volume attach detach reconciler sync. Disabling this may cause volumes to be mismatched with pods. Use wisely.
--enable-dynamic-provisioning     Default: true
Enable dynamic provisioning for environments that support it.
--enable-garbage-collector     Default: true
Enables the generic garbage collector. MUST be synced with the corresponding flag of the kube-apiserver.
--enable-hostpath-provisioner
Enable HostPath PV provisioning when running without a cloud provider. This allows testing and development of provisioning features. HostPath provisioning is not supported in any way, won't work in a multi-node cluster, and should not be used for anything other than testing or development.
--enable-taint-manager     Default: true
WARNING: Beta feature. If set to true enables NoExecute Taints and will evict all not-tolerating Pod running on Nodes tainted with this kind of Taints.
--experimental-cluster-signing-duration duration     Default: 8760h0m0s
The length of duration signed certificates will be given.
--external-cloud-volume-plugin string
The plugin to use when cloud provider is set to external. Can be empty, should only be set when cloud-provider is external. Currently used to allow node and volume controllers to work for in tree cloud providers.
--feature-gates mapStringBool
A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:
APIListChunking=true|false (BETA - default=true)
APIResponseCompression=true|false (ALPHA - default=false)
AllAlpha=true|false (ALPHA - default=false)
AppArmor=true|false (BETA - default=true)
AttachVolumeLimit=true|false (BETA - default=true)
BalanceAttachedNodeVolumes=true|false (ALPHA - default=false)
BlockVolume=true|false (BETA - default=true)
BoundServiceAccountTokenVolume=true|false (ALPHA - default=false)
CPUManager=true|false (BETA - default=true)
CRIContainerLogRotation=true|false (BETA - default=true)
CSIBlockVolume=true|false (BETA - default=true)
CSIDriverRegistry=true|false (BETA - default=true)
CSIInlineVolume=true|false (ALPHA - default=false)
CSIMigration=true|false (ALPHA - default=false)
CSIMigrationAWS=true|false (ALPHA - default=false)
CSIMigrationGCE=true|false (ALPHA - default=false)
CSIMigrationOpenStack=true|false (ALPHA - default=false)
CSINodeInfo=true|false (BETA - default=true)
CustomCPUCFSQuotaPeriod=true|false (ALPHA - default=false)
CustomResourcePublishOpenAPI=true|false (ALPHA - default=false)
CustomResourceSubresources=true|false (BETA - default=true)
CustomResourceValidation=true|false (BETA - default=true)
CustomResourceWebhookConversion=true|false (ALPHA - default=false)
DebugContainers=true|false (ALPHA - default=false)
DevicePlugins=true|false (BETA - default=true)
DryRun=true|false (BETA - default=true)
DynamicAuditing=true|false (ALPHA - default=false)
DynamicKubeletConfig=true|false (BETA - default=true)
ExpandCSIVolumes=true|false (ALPHA - default=false)
ExpandInUsePersistentVolumes=true|false (ALPHA - default=false)
ExpandPersistentVolumes=true|false (BETA - default=true)
ExperimentalCriticalPodAnnotation=true|false (ALPHA - default=false)
ExperimentalHostUserNamespaceDefaulting=true|false (BETA - default=false)
HyperVContainer=true|false (ALPHA - default=false)
KubeletPodResources=true|false (ALPHA - default=false)
LocalStorageCapacityIsolation=true|false (BETA - default=true)
MountContainers=true|false (ALPHA - default=false)
NodeLease=true|false (BETA - default=true)
PodShareProcessNamespace=true|false (BETA - default=true)
ProcMountType=true|false (ALPHA - default=false)
QOSReserved=true|false (ALPHA - default=false)
ResourceLimitsPriorityFunction=true|false (ALPHA - default=false)
ResourceQuotaScopeSelectors=true|false (BETA - default=true)
RotateKubeletClientCertificate=true|false (BETA - default=true)
RotateKubeletServerCertificate=true|false (BETA - default=true)
RunAsGroup=true|false (BETA - default=true)
RuntimeClass=true|false (BETA - default=true)
SCTPSupport=true|false (ALPHA - default=false)
ScheduleDaemonSetPods=true|false (BETA - default=true)
ServerSideApply=true|false (ALPHA - default=false)
ServiceNodeExclusion=true|false (ALPHA - default=false)
StorageVersionHash=true|false (ALPHA - default=false)
StreamingProxyRedirects=true|false (BETA - default=true)
SupportNodePidsLimit=true|false (ALPHA - default=false)
SupportPodPidsLimit=true|false (BETA - default=true)
Sysctls=true|false (BETA - default=true)
TTLAfterFinished=true|false (ALPHA - default=false)
TaintBasedEvictions=true|false (BETA - default=true)
TaintNodesByCondition=true|false (BETA - default=true)
TokenRequest=true|false (BETA - default=true)
TokenRequestProjection=true|false (BETA - default=true)
ValidateProxyRedirects=true|false (BETA - default=true)
VolumeSnapshotDataSource=true|false (ALPHA - default=false)
VolumeSubpathEnvExpansion=true|false (ALPHA - default=false)
WinDSR=true|false (ALPHA - default=false)
WinOverlay=true|false (ALPHA - default=false)
WindowsGMSA=true|false (ALPHA - default=false)
--flex-volume-plugin-dir string     Default: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/"
Full path of the directory in which the flex volume plugin should search for additional third party volume plugins.
-h, --help
help for kube-controller-manager
--horizontal-pod-autoscaler-cpu-initialization-period duration     Default: 5m0s
The period after pod start when CPU samples might be skipped.
--horizontal-pod-autoscaler-downscale-stabilization duration     Default: 5m0s
The period for which autoscaler will look backwards and not scale down below any recommendation it made during that period.
--horizontal-pod-autoscaler-initial-readiness-delay duration     Default: 30s
The period after pod start during which readiness changes will be treated as initial readiness.
--horizontal-pod-autoscaler-sync-period duration     Default: 15s
The period for syncing the number of pods in horizontal pod autoscaler.
--horizontal-pod-autoscaler-tolerance float     Default: 0.1
The minimum change (from 1.0) in the desired-to-actual metrics ratio for the horizontal pod autoscaler to consider scaling.
--http2-max-streams-per-connection int
The limit that the server gives to clients for the maximum number of streams in an HTTP/2 connection. Zero means to use golang's default.
--kube-api-burst int32     Default: 30
Burst to use while talking with kubernetes apiserver.
--kube-api-content-type string     Default: "application/vnd.kubernetes.protobuf"
Content type of requests sent to apiserver.
--kube-api-qps float32     Default: 20
QPS to use while talking with kubernetes apiserver.
--kubeconfig string
Path to kubeconfig file with authorization and master location information.
--large-cluster-size-threshold int32     Default: 50
Number of nodes from which NodeController treats the cluster as large for the eviction logic purposes. --secondary-node-eviction-rate is implicitly overridden to 0 for clusters this size or smaller.
--leader-elect     Default: true
Start a leader election client and gain leadership before executing the main loop. Enable this when running replicated components for high availability.
--leader-elect-lease-duration duration     Default: 15s
The duration that non-leader candidates will wait after observing a leadership renewal until attempting to acquire leadership of a led but unrenewed leader slot. This is effectively the maximum duration that a leader can be stopped before it is replaced by another candidate. This is only applicable if leader election is enabled.
--leader-elect-renew-deadline duration     Default: 10s
The interval between attempts by the acting master to renew a leadership slot before it stops leading. This must be less than or equal to the lease duration. This is only applicable if leader election is enabled.
--leader-elect-resource-lock endpoints     Default: "endpoints"
The type of resource object that is used for locking during leader election. Supported options are endpoints (default) and `configmaps`.
--leader-elect-retry-period duration     Default: 2s
The duration the clients should wait between attempting acquisition and renewal of a leadership. This is only applicable if leader election is enabled.
--log-backtrace-at traceLocation     Default: :0
when logging hits line file:N, emit a stack trace
--log-dir string
If non-empty, write log files in this directory
--log-file string
If non-empty, use this log file
--log-flush-frequency duration     Default: 5s
Maximum number of seconds between log flushes
--logtostderr     Default: true
log to standard error instead of files
--master string
The address of the Kubernetes API server (overrides any value in kubeconfig).
--min-resync-period duration     Default: 12h0m0s
The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod.
--namespace-sync-period duration     Default: 5m0s
The period for syncing namespace life-cycle updates
--node-cidr-mask-size int32     Default: 24
Mask size for node cidr in cluster.
--node-eviction-rate float32     Default: 0.1
Number of nodes per second on which pods are deleted in case of node failure when a zone is healthy (see --unhealthy-zone-threshold for definition of healthy/unhealthy). Zone refers to entire cluster in non-multizone clusters.
--node-monitor-grace-period duration     Default: 40s
Amount of time which we allow running Node to be unresponsive before marking it unhealthy. Must be N times more than kubelet's nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet to post node status.
--node-monitor-period duration     Default: 5s
The period for syncing NodeStatus in NodeController.
--node-startup-grace-period duration     Default: 1m0s
Amount of time which we allow starting Node to be unresponsive before marking it unhealthy.
--pod-eviction-timeout duration     Default: 5m0s
The grace period for deleting pods on failed nodes.
--profiling
Enable profiling via web interface host:port/debug/pprof/
--pv-recycler-increment-timeout-nfs int32     Default: 30
the increment of time added per Gi to ActiveDeadlineSeconds for an NFS scrubber pod
--pv-recycler-minimum-timeout-hostpath int32     Default: 60
The minimum ActiveDeadlineSeconds to use for a HostPath Recycler pod. This is for development and testing only and will not work in a multi-node cluster.
--pv-recycler-minimum-timeout-nfs int32     Default: 300
The minimum ActiveDeadlineSeconds to use for an NFS Recycler pod
--pv-recycler-pod-template-filepath-hostpath string
The file path to a pod definition used as a template for HostPath persistent volume recycling. This is for development and testing only and will not work in a multi-node cluster.
--pv-recycler-pod-template-filepath-nfs string
The file path to a pod definition used as a template for NFS persistent volume recycling
--pv-recycler-timeout-increment-hostpath int32     Default: 30
the increment of time added per Gi to ActiveDeadlineSeconds for a HostPath scrubber pod. This is for development and testing only and will not work in a multi-node cluster.
--pvclaimbinder-sync-period duration     Default: 15s
The period for syncing persistent volumes and persistent volume claims
--requestheader-allowed-names stringSlice
List of client certificate common names to allow to provide usernames in headers specified by --requestheader-username-headers. If empty, any client certificate validated by the authorities in --requestheader-client-ca-file is allowed.
--requestheader-client-ca-file string
Root certificate bundle to use to verify client certificates on incoming requests before trusting usernames in headers specified by --requestheader-username-headers. WARNING: generally do not depend on authorization being already done for incoming requests.
--requestheader-extra-headers-prefix stringSlice     Default: [x-remote-extra-]
List of request header prefixes to inspect. X-Remote-Extra- is suggested.
--requestheader-group-headers stringSlice     Default: [x-remote-group]
List of request headers to inspect for groups. X-Remote-Group is suggested.
--requestheader-username-headers stringSlice     Default: [x-remote-user]
List of request headers to inspect for usernames. X-Remote-User is common.
--resource-quota-sync-period duration     Default: 5m0s
The period for syncing quota usage status in the system
--root-ca-file string
If set, this root certificate authority will be included in service account's token secret. This must be a valid PEM-encoded CA bundle.
--route-reconciliation-period duration     Default: 10s
The period for reconciling routes created for Nodes by cloud provider.
--secondary-node-eviction-rate float32     Default: 0.01
Number of nodes per second on which pods are deleted in case of node failure when a zone is unhealthy (see --unhealthy-zone-threshold for definition of healthy/unhealthy). Zone refers to entire cluster in non-multizone clusters. This value is implicitly overridden to 0 if the cluster size is smaller than --large-cluster-size-threshold.
--secure-port int     Default: 10257
The port on which to serve HTTPS with authentication and authorization.If 0, don't serve HTTPS at all.
--service-account-private-key-file string
Filename containing a PEM-encoded private RSA or ECDSA key used to sign service account tokens.
--service-cluster-ip-range string
CIDR Range for Services in cluster. Requires --allocate-node-cidrs to be true
--skip-headers
If true, avoid header prefixes in the log messages
--stderrthreshold severity     Default: 2
logs at or above this threshold go to stderr
--terminated-pod-gc-threshold int32     Default: 12500
Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled.
--tls-cert-file string
File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert). If HTTPS serving is enabled, and --tls-cert-file and --tls-private-key-file are not provided, a self-signed certificate and key are generated for the public address and saved to the directory specified by --cert-dir.
--tls-cipher-suites stringSlice
Comma-separated list of cipher suites for the server. If omitted, the default Go cipher suites will be use. Possible values: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_RC4_128_SHA
--tls-min-version string
Minimum TLS version supported. Possible values: VersionTLS10, VersionTLS11, VersionTLS12
--tls-private-key-file string
File containing the default x509 private key matching --tls-cert-file.
--tls-sni-cert-key namedCertKey     Default: []
A pair of x509 certificate and private key file paths, optionally suffixed with a list of domain patterns which are fully qualified domain names, possibly with prefixed wildcard segments. If no domain patterns are provided, the names of the certificate are extracted. Non-wildcard matches trump over wildcard matches, explicit domain patterns trump over extracted names. For multiple key/certificate pairs, use the --tls-sni-cert-key multiple times. Examples: "example.crt,example.key" or "foo.crt,foo.key:*.foo.com,foo.com".
--unhealthy-zone-threshold float32     Default: 0.55
Fraction of Nodes in a zone which needs to be not Ready (minimum 3) for zone to be treated as unhealthy.
--use-service-account-credentials
If true, use individual service account credentials for each controller.
-v, --v Level
number for the log level verbosity
--version version[=true]
Print version information and quit
--vmodule moduleSpec
comma-separated list of pattern=N settings for file-filtered logging
+ + diff --git a/content/zh/docs/reference/federation/_index.html b/content/zh/docs/reference/federation/_index.html new file mode 100644 index 0000000000000..73b1875340882 --- /dev/null +++ b/content/zh/docs/reference/federation/_index.html @@ -0,0 +1,11 @@ +--- +title: "联邦 API" +weight: 40 +--- + + diff --git a/content/zh/docs/reference/glossary/aggregation-layer.md b/content/zh/docs/reference/glossary/aggregation-layer.md new file mode 100644 index 0000000000000..982c7ef3a2cbb --- /dev/null +++ b/content/zh/docs/reference/glossary/aggregation-layer.md @@ -0,0 +1,45 @@ +--- +title: 聚合层 +id: aggregation-layer +date: 2018-10-08 +full_link: /docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/ +short_description: > + 聚合层允许您在自己的集群上安装额外的 Kubernetes 风格的 API。 + +aka: +tags: +- architecture +- extension +- operation +--- + + + + + +聚合层允许您在自己的集群上安装额外的 Kubernetes 风格的 API。 + + + + + +当您配置了 {{< glossary_tooltip text="Kubernetes API Server" term_id="kube-apiserver" >}} 来 [支持额外的 API](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/),您就可以在 Kubernetes API 中增加 `APIService` 对象来 "申领(Claim)" 一个 URL 路径。 diff --git a/content/zh/docs/reference/glossary/annotation.md b/content/zh/docs/reference/glossary/annotation.md new file mode 100644 index 0000000000000..75705d9745219 --- /dev/null +++ b/content/zh/docs/reference/glossary/annotation.md @@ -0,0 +1,42 @@ +--- +title: 注解 +id: annotation +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/annotations +short_description: > + 注解是以键值对的形式给资源对象附加随机的无法标识的元数据。 + +aka: +tags: +- fundamental +--- + + + + + + 注解是以键值对的形式给资源对象附加随机的无法标识的元数据。 + + + + + +注解中的元数据可大可小,可以是结构化的也可以是非结构化的,并且能包含标签不允许使用的字符。像工具和软件库这样的客户端可以检索这些元数据。 + diff --git a/content/zh/docs/reference/glossary/application-architect.md b/content/zh/docs/reference/glossary/application-architect.md new file mode 100644 index 0000000000000..849d1b768532d --- /dev/null +++ b/content/zh/docs/reference/glossary/application-architect.md @@ -0,0 +1,37 @@ +--- +title: 应用架构师 +id: application-architect +date: 2018-04-12 +full_link: +short_description: > + 应用架构师是负责应用高级设计的人。 + +aka: +tags: +- user-type +--- + 应用架构师是负责应用高级设计的人。 + + + + + + +应用架构师确保应用的实现允许它和周边组件进行可扩展的、可持续的交互。周边组件包括数据库、日志基础设施和其他微服务。 + diff --git a/content/zh/docs/reference/glossary/application-developer.md b/content/zh/docs/reference/glossary/application-developer.md new file mode 100644 index 0000000000000..65650133dac5f --- /dev/null +++ b/content/zh/docs/reference/glossary/application-developer.md @@ -0,0 +1,41 @@ +--- +title: 应用开发者 +id: application-developer +date: 2018-04-12 +full_link: +short_description: > + 编写可以在 Kubernetes 集群上运行的应用的人。 + +aka: +tags: +- user-type +--- + + + + + +编写可以在 Kubernetes 集群上运行的应用的人。 + + + + + +应用开发者专注于应用的某一部分。他们工作范围的大小有明显的差异。 diff --git a/content/zh/docs/reference/glossary/approver.md b/content/zh/docs/reference/glossary/approver.md new file mode 100755 index 0000000000000..879ef5e58b6d5 --- /dev/null +++ b/content/zh/docs/reference/glossary/approver.md @@ -0,0 +1,40 @@ +--- +title: 批准者 +id: approver +date: 2018-04-12 +full_link: +short_description: > + 可以审核并批准 Kubernetes 代码贡献的人。 + +aka: +tags: +- community +--- + + + + 可以审核并批准 Kubernetes 代码贡献的人。 + + + + + +代码审核的重点是代码质量和正确性,而批准的重点是对贡献的整体接受。 +整体接受包括向后/向前兼容性、遵守 API 和参数约定、细微的性能和正确性问题、与系统其他部分的交互等。 +批准者状态的作用域是代码库的一部分。 +审批者以前被称为维护者。 diff --git a/content/zh/docs/reference/glossary/certificate.md b/content/zh/docs/reference/glossary/certificate.md new file mode 100644 index 0000000000000..238178c8908ee --- /dev/null +++ b/content/zh/docs/reference/glossary/certificate.md @@ -0,0 +1,42 @@ +--- +title: 证书 +id: certificate +date: 2018-04-12 +full_link: /docs/tasks/tls/managing-tls-in-a-cluster/ +short_description: > + 证书是个安全加密文件,用来确认对 Kubernetes 集群访问的合法性。 + +aka: +tags: +- security +--- + + + + + +证书是个安全加密文件,用来确认对 Kubernetes 集群访问的合法性。 + + + + + +证书可以让 Kubernetes 集群中运行的应用程序安全的访问 Kubernetes API。证书可以确认客户端是否被允许访问 API。 + diff --git a/content/zh/docs/reference/glossary/cla.md b/content/zh/docs/reference/glossary/cla.md new file mode 100644 index 0000000000000..dae58a89e626a --- /dev/null +++ b/content/zh/docs/reference/glossary/cla.md @@ -0,0 +1,38 @@ +--- +title: CLA (贡献者许可协议) +id: cla +date: 2018-04-12 +full_link: https://github.com/kubernetes/community/blob/master/CLA.md +short_description: > + 贡献者对他们在开源项目中所贡献的代码的授权许可条款。 + +aka: +tags: +- community +--- + + + + {{< glossary_tooltip text="贡献者" term_id="contributor" >}} 对他们在开源项目中所贡献的代码的授权许可条款。 + + + + + +CLA 对解决贡献者在开源社区所贡献的资料和智力资产(IP)导致的法律纠纷很有帮助。 + diff --git a/content/zh/docs/reference/glossary/cloud-controller-manager.md b/content/zh/docs/reference/glossary/cloud-controller-manager.md new file mode 100755 index 0000000000000..b6254d7ce9791 --- /dev/null +++ b/content/zh/docs/reference/glossary/cloud-controller-manager.md @@ -0,0 +1,47 @@ +--- +title: 云控制器管理器 +id: cloud-controller-manager +date: 2018-04-12 +full_link: /docs/tasks/administer-cluster/running-cloud-controller/ +short_description: > + 云控制器管理器是 1.8 的 alpha 特性。在未来发布的版本中,这是将 Kubernetes 与任何其他云集成的最佳方式。 + +aka: +tags: +- core-object +- architecture +- operation +--- + + + + + +云控制器管理器是 1.8 的 alpha 特性。在未来发布的版本中,这是将 Kubernetes 与任何其他云集成的最佳方式。 + + + + + +Kubernetes v1.6 包含一个新的可执行文件叫做 cloud-controller-manager。cloud-controller-manager 是一个守护进程,其中嵌入了特定于某云环境的控制环。 +这些特定于云环境的控制环最初位于 kube-controller-manager 中。 +由于云供应商的开发和发布节奏与 Kubernetes 项目不同步,将特定于供应商的代码抽象到 cloud-controller-manager 可执行文件可以允许云供应商独立于核心 Kubernetes 代码进行演进。 diff --git a/content/zh/docs/reference/glossary/cloud-provider.md b/content/zh/docs/reference/glossary/cloud-provider.md new file mode 100644 index 0000000000000..16851569d62ed --- /dev/null +++ b/content/zh/docs/reference/glossary/cloud-provider.md @@ -0,0 +1,38 @@ +--- +title: 云供应商 +id: cloud-provider +date: 2018-04-12 +full_link: /docs/concepts/cluster-administration/cloud-providers +short_description: > + 云供应商是提供可以用来运行 Kubernetes 集群的云计算平台的公司。 + +aka: +tags: +- community +--- + + + + 云供应商是提供可以用来运行 Kubernetes 集群的云计算平台的公司。 + + + + +云供应商也叫云服务供应商(CSPs),他们可以为用户提供云计算平台。他们提供的服务可以是基础设施即服务(IaaS)或者平台即服务(PaaS)。云供应商除了运行 Kubernetes 集群,还提供一些集群交互的服务,例如负载均衡(Load Balancers)、存储类别(Storage Classes)等。 diff --git a/content/zh/docs/reference/glossary/cluster-architect.md b/content/zh/docs/reference/glossary/cluster-architect.md new file mode 100644 index 0000000000000..c45bcfbe349a0 --- /dev/null +++ b/content/zh/docs/reference/glossary/cluster-architect.md @@ -0,0 +1,37 @@ +--- +title: 集群架构师 +id: cluster-architect +date: 2018-04-12 +full_link: +short_description: > + 集群架构师负责设计集群的基础设施,可能包含一个或多个 Kubernetes 集群。 + +aka: +tags: +- user-type +--- + + + + 集群架构师负责设计集群的基础设施,可能包含一个或多个 Kubernetes 集群。 + + + + + +集群架构师要具备分布式系统的最佳实践经验,例如:高可用性和安全性。 diff --git a/content/zh/docs/reference/glossary/cluster-operator.md b/content/zh/docs/reference/glossary/cluster-operator.md new file mode 100644 index 0000000000000..8318dd46edffa --- /dev/null +++ b/content/zh/docs/reference/glossary/cluster-operator.md @@ -0,0 +1,44 @@ +--- +title: 集群操作者 +id: cluster-operator +date: 2018-04-12 +full_link: +short_description: > + 配置、控制、监控集群的人。 + +aka: +tags: +- user-type +--- + + + + + 配置、控制、监控集群的人。 + + + + +他们的主要责任是保持集群正常运行,可能需要进行周期性的维护和升级活动。
+ +**注意:** 集群操作者不同于[操作者模式(Operator Pattern)](https://coreos.com/operators),操作者模式是用来扩展 Kubernetes API 的。 + diff --git a/content/zh/docs/reference/glossary/cluster.md b/content/zh/docs/reference/glossary/cluster.md new file mode 100644 index 0000000000000..8cc5502ed20c2 --- /dev/null +++ b/content/zh/docs/reference/glossary/cluster.md @@ -0,0 +1,43 @@ +--- +title: 集群 +id: cluster +date: 2018-04-12 +full_link: +short_description: > + 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。 + +aka: +tags: +- fundamental +- operation +--- + + + + + + 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。 + + + + + +集群由至少一个主节点和若干个工作节点组成。 diff --git a/content/zh/docs/reference/glossary/cni.md b/content/zh/docs/reference/glossary/cni.md new file mode 100644 index 0000000000000..361a7f09117be --- /dev/null +++ b/content/zh/docs/reference/glossary/cni.md @@ -0,0 +1,44 @@ +--- +title: CNI (容器网络接口) +id: cni +date: 2018-05-25 +full_link: /docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni +short_description: > + 容器网络接口 (CNI) 插件是遵循 appc/CNI 协议的一类网络插件。 + + +aka: +tags: +- networking +--- + + + + + + 容器网络接口 (CNI) 插件是遵循 appc/CNI 协议的一类网络插件。 + + + + + +* 想了解 Kubernetes 和 CNI 请参考 ["网络插件"](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni)。 diff --git a/content/zh/docs/reference/glossary/code-contributor.md b/content/zh/docs/reference/glossary/code-contributor.md new file mode 100644 index 0000000000000..8d24d7f72f589 --- /dev/null +++ b/content/zh/docs/reference/glossary/code-contributor.md @@ -0,0 +1,43 @@ +--- +title: 代码贡献者 +id: code-contributor +date: 2018-04-12 +full_link: /docs/community/devel/ +short_description: > + 为 Kubernetes 开源代码库开发并贡献代码的人。 + +aka: +tags: +- community +- user-type +--- + + + + + + 为 Kubernetes 开源代码库开发并贡献代码的人。 + + + + + +代码贡献者也是加入一个或多个 {{< glossary_tooltip text="特别兴趣小组 (SIGs)" term_id="sig" >}} 的活跃的 {{< glossary_tooltip text="社区成员" term_id="member" >}}。 diff --git a/content/zh/docs/reference/glossary/configmap.md b/content/zh/docs/reference/glossary/configmap.md new file mode 100644 index 0000000000000..d3d0945cdc601 --- /dev/null +++ b/content/zh/docs/reference/glossary/configmap.md @@ -0,0 +1,41 @@ +--- +title: ConfigMap +id: configmap +date: 2018-04-12 +full_link: /docs/tasks/configure-pod-container/configure-pod-configmap/ +short_description: > + ConfigMap 是一种 API 对象,用来将非机密性的数据保存到健值对中。使用时可以用作环境变量、命令行参数或者存储卷中的配置文件。 + +aka: +tags: +- core-object +--- + + + + + + ConfigMap 是一种 API 对象,用来将非机密性的数据保存到健值对中。使用时可以用作环境变量、命令行参数或者存储卷中的配置文件。 + + + + + +ConfigMap 将您的环境配置信息和 {{< glossary_tooltip text="容器镜像" term_id="container" >}} 解耦,便于应用配置的修改。当您需要储存机密信息时可以使用 [Secret](/docs/concepts/configuration/secret/) 对象。 diff --git a/content/zh/docs/reference/glossary/container-env-variables.md b/content/zh/docs/reference/glossary/container-env-variables.md new file mode 100644 index 0000000000000..d851c14c92b0a --- /dev/null +++ b/content/zh/docs/reference/glossary/container-env-variables.md @@ -0,0 +1,40 @@ +--- +title: 容器环境变量 +id: container-env-variables +date: 2018-04-12 +full_link: /docs/concepts/containers/container-environment-variables.md +short_description: > + 容器环境变量提供了运行容器化应用所必须的一些重要信息。 + +aka: +tags: +- fundamental +--- + + + + + + 容器环境变量提供了运行容器化应用所必须的一些重要信息。 + + + + + 容器环境变量为运行中的容器化应用提供必要的信息,同时还提供与 {{< glossary_tooltip text="容器" term_id="container" >}} 重要资源相关的其他信息,例如:文件系统信息、容器自身的信息以及其他像服务端点(Service endpoints)这样的集群资源信息。 diff --git a/content/zh/docs/reference/glossary/container-lifecycle-hooks.md b/content/zh/docs/reference/glossary/container-lifecycle-hooks.md new file mode 100644 index 0000000000000..3d1b708fe0d54 --- /dev/null +++ b/content/zh/docs/reference/glossary/container-lifecycle-hooks.md @@ -0,0 +1,38 @@ +--- +title: 容器生命周期钩子 +id: container-lifecycle-hooks +date: 2018-10-08 +full_link: /docs/concepts/containers/container-lifecycle-hooks/ +short_description: > + 生命周期钩子暴露容器管理生命周期中的事件,允许用户在事件发生时运行代码。 + +aka: +tags: +- extension +--- + + + 生命周期钩子暴露{{< glossary_tooltip text="容器" term_id="container" >}}管理生命周期中的事件,允许用户在事件发生时运行代码。 + + + + +针对容器暴露了两个钩子:PostStart 在容器创建之后立即执行,PreStop 在容器停止之前立即阻塞并被调用。 + diff --git a/content/zh/docs/reference/glossary/container.md b/content/zh/docs/reference/glossary/container.md new file mode 100644 index 0000000000000..16d99f4e30609 --- /dev/null +++ b/content/zh/docs/reference/glossary/container.md @@ -0,0 +1,44 @@ +--- +title: 容器 +id: container +date: 2018-04-12 +full_link: /docs/concepts/overview/what-is-kubernetes/#why-containers +short_description: > + 容器是可移植、可执行的轻量级的镜像,镜像中包含软件及其相关依赖。 + +aka: +tags: +- fundamental +- workload +--- + + + + + + 容器是可移植、可执行的轻量级的镜像,镜像中包含软件及其相关依赖。 + + + + + +容器使应用和底层的主机基础设施解耦,降低了应用在不同云环境或者操作系统上的部署难度,便于应用扩展。 + diff --git a/content/zh/docs/reference/glossary/contributor.md b/content/zh/docs/reference/glossary/contributor.md new file mode 100755 index 0000000000000..32f21a5e54b77 --- /dev/null +++ b/content/zh/docs/reference/glossary/contributor.md @@ -0,0 +1,39 @@ +--- +title: 贡献者 +id: contributor +date: 2018-04-12 +full_link: +short_description: > + 通过贡献代码、文档或者投入时间等方式来帮助 Kubernetes 项目或社区的人。 + +aka: +tags: +- community +--- + + + + + +通过贡献代码、文档或者投入时间等方式来帮助 Kubernetes 项目或社区的人。 + + + + +贡献形式包括提交拉取请求(PRs)、问题报告(Issues)、反馈、参与{{< glossary_tooltip text="特别兴趣小组(SIG)" term_id="sig" >}}或者组织社区活动等等。 + diff --git a/content/zh/docs/reference/glossary/controller.md b/content/zh/docs/reference/glossary/controller.md new file mode 100644 index 0000000000000..2b523c8b76f3e --- /dev/null +++ b/content/zh/docs/reference/glossary/controller.md @@ -0,0 +1,40 @@ +--- +title: 控制器 +id: controller +date: 2018-04-12 +full_link: /docs/admin/kube-controller-manager/ +short_description: > + 控制器通过 apiserver 监控集群的公共状态,并致力于将当前状态转变为期望的状态。 + +aka: +tags: +- architecture +- fundamental +--- + + + + 控制器通过 {{< glossary_tooltip text="apiserver" term_id="kube-apiserver" >}} 监控集群的公共状态,并致力于将当前状态转变为期望的状态。 + + + + + +Kubernetes 当前提供的部分控制器例子包括:副本控制器(replication controller)、端点控制器(endpoints controller)、命名空间控制器(namespace controller)、服务账号控制器(serviceaccounts controller)。 + diff --git a/content/zh/docs/reference/glossary/cronjob.md b/content/zh/docs/reference/glossary/cronjob.md new file mode 100644 index 0000000000000..5af7746647c6a --- /dev/null +++ b/content/zh/docs/reference/glossary/cronjob.md @@ -0,0 +1,43 @@ +--- +title: CronJob +id: cronjob +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/cron-jobs/ +short_description: > + 管理定期运行的 [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/)。 + +aka: +tags: +- core-object +- workload +--- + + + + + + 管理定期运行的 [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/)。 + + + + + +Cronjob 对象类似 *crontab* 文件中的一行命令,它声明了一个遵循 [Cron](https://en.wikipedia.org/wiki/Cron) 格式的调度任务。 diff --git a/content/zh/docs/reference/glossary/csi.md b/content/zh/docs/reference/glossary/csi.md new file mode 100644 index 0000000000000..afacbf8f1d072 --- /dev/null +++ b/content/zh/docs/reference/glossary/csi.md @@ -0,0 +1,48 @@ +--- +title: 容器存储接口 (CSI) +id: csi +date: 2018-06-25 +full_link: /docs/concepts/storage/volumes/#csi +short_description: > + 容器存储接口 (CSI)定义了存储系统暴露给容器的标准接口。 + + +aka: +tags: +- storage +--- + + + + + 容器存储接口 (CSI)定义了存储系统暴露给容器的标准接口。 + + + + + +CSI 允许存储驱动提供商为 Kubernetes 创建定制化的存储插件,而无需将这些插件的代码添加到 Kubernetes 代码仓库(外部插件)。要使用某个存储提供商的 CSI 驱动,你首先要[将它部署到你的集群上](https://kubernetes-csi.github.io/docs/Setup.html)。然后你才能创建使用该 CSI 驱动的 {{< glossary_tooltip text="Storage Class" term_id="storage-class" >}} 。 + +* [Kubernetes 文档中关于 CSI 的描述](/docs/concepts/storage/volumes/#csi) +* [可用的 CSI 驱动列表](https://kubernetes-csi.github.io/docs/Drivers.html) diff --git a/content/zh/docs/reference/glossary/customresourcedefinition.md b/content/zh/docs/reference/glossary/customresourcedefinition.md new file mode 100644 index 0000000000000..510d26d3bc52f --- /dev/null +++ b/content/zh/docs/reference/glossary/customresourcedefinition.md @@ -0,0 +1,46 @@ +--- +title: CustomResourceDefinition +id: CustomResourceDefinition +date: 2018-04-12 +full_link: docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/ +short_description: > + 通过定制化的代码给您的 Kubernetes API 服务器增加资源对象,而无需编译完整的定制 API 服务器。 + +aka: +tags: +- fundamental +- operation +- extension +--- + + + + + + 通过定制化的代码给您的 Kubernetes API 服务器增加资源对象,而无需编译完整的定制 API 服务器。 + + + + + +当 Kubernetes 公开支持的 API 资源不能满足您的需要时,定制资源对象(Custom Resource Definitions)让您可以在您的环境上扩展 Kubernetes API。 + diff --git a/content/zh/docs/reference/glossary/daemonset.md b/content/zh/docs/reference/glossary/daemonset.md new file mode 100644 index 0000000000000..f0ec7e9cdab9d --- /dev/null +++ b/content/zh/docs/reference/glossary/daemonset.md @@ -0,0 +1,43 @@ +--- +title: DaemonSet +id: daemonset +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/daemonset +short_description: > + 确保 Pod 的副本在集群中的一组节点上运行。 + +aka: +tags: +- fundamental +- core-object +- workload +--- + + + + 确保 {{< glossary_tooltip text="Pod" term_id="pod" >}} 的副本在{{< glossary_tooltip text="集群" term_id="cluster" >}}中的一组节点上运行。 + + + + +用来部署系统守护进程,例如日志搜集和监控代理,这些进程通常必须运行在每个{{< glossary_tooltip text="节点" term_id="node" >}}上。 + diff --git a/content/zh/docs/reference/glossary/deployment.md b/content/zh/docs/reference/glossary/deployment.md new file mode 100644 index 0000000000000..08abdc60c89bc --- /dev/null +++ b/content/zh/docs/reference/glossary/deployment.md @@ -0,0 +1,45 @@ +--- +title: Deployment +id: deployment +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/deployment/ +short_description: > + Deployment 是管理应用副本的 API 对象。 + +aka: +tags: +- fundamental +- core-object +- workload +--- + + + + + + Deployment 是管理应用副本的 API 对象。 + + + + + +应用的每个副本就是一个 {{< glossary_tooltip term_id="pod" >}},并且这些 Pod 会分散运行在集群的节点上。 diff --git a/content/zh/docs/reference/glossary/developer.md b/content/zh/docs/reference/glossary/developer.md new file mode 100755 index 0000000000000..2efbeea6e2e16 --- /dev/null +++ b/content/zh/docs/reference/glossary/developer.md @@ -0,0 +1,42 @@ +--- +title: 开发者 (释疑) +id: developer +date: 2018-04-12 +full_link: +short_description: > + 指的是:应用开发者、代码贡献者、或平台开发者。 + +aka: +tags: +- community +- user-type +--- + + + + 指的是: {{< glossary_tooltip text="应用开发者" term_id="application-developer" >}}、 {{< glossary_tooltip text="代码贡献者" term_id="code-contributor" >}}、或 {{< glossary_tooltip text="平台开发者" term_id="platform-developer" >}}。 + + + + + +根据上下文的不同,“开发者”这个被多处使用的词条会有不同的含义。 + + + diff --git a/content/zh/docs/reference/glossary/device-plugin.md b/content/zh/docs/reference/glossary/device-plugin.md new file mode 100644 index 0000000000000..9b900a5a414f5 --- /dev/null +++ b/content/zh/docs/reference/glossary/device-plugin.md @@ -0,0 +1,33 @@ +--- +title: 驱动插件 +id: device-plugin +date: 2019-02-02 +full_link: /docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ +short_description: > + 驱动插件是运行在 Kubernetes 中的容器,它提供对供应商特定资源的访问。 +aka: +tags: +- fundamental +- extension +--- + + + + + +[驱动插件](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)是运行在 Kubernetes 中的容器,它提供对供应商特定资源的访问。驱动插件将这些资源发布到 kubelet,并且可以手动部署或做为 DeamonSet 部署,而不用编写定制的 Kubernetes 代码。 diff --git a/content/zh/docs/reference/glossary/docker.md b/content/zh/docs/reference/glossary/docker.md new file mode 100755 index 0000000000000..1d7c9a85116b0 --- /dev/null +++ b/content/zh/docs/reference/glossary/docker.md @@ -0,0 +1,41 @@ +--- +title: docker +id: docker +date: 2018-04-12 +full_link: /docs/reference/kubectl/docker-cli-to-kubectl/ +short_description: > + Docker 是一种可以提供操作系统级别虚拟化(也称作容器)的软件技术。 + +aka: +tags: +- fundamental +--- + + + + + + Docker 是一种可以提供操作系统级别虚拟化(也称作容器)的软件技术 + + + + + +Docker 使用了 Linux 内核中的资源隔离特性(如 cgroup 和内核命名空间)以及支持联合文件系统(如 OverlayFS 和其他),允许多个相互独立的“容器”一起运行在同一 Linux 实例上,从而避免启动和维护虚拟机(VMs)的开销。 diff --git a/content/zh/docs/reference/glossary/downstream.md b/content/zh/docs/reference/glossary/downstream.md new file mode 100755 index 0000000000000..54f66a2bb1566 --- /dev/null +++ b/content/zh/docs/reference/glossary/downstream.md @@ -0,0 +1,44 @@ +--- +title: 下游(消除歧义) +id: downstream +date: 2018-04-12 +full_link: +short_description: > + 可以指:Kubernetes 生态系统中依赖于核心 Kubernetes 代码库或分支代码库的代码。 + +aka: +tags: +- community +--- + + + +<-- +May refer to: code in the Kubernetes ecosystem that depends upon the core Kubernetes codebase or a forked repo. +--> + +可以指:Kubernetes 生态系统中依赖于核心 Kubernetes 代码库或分支代码库的代码。 + + + + + +* 在 **Kubernetes 社区**中:*下游(downstream)* 在人们交流中常用来表示那些依赖核心 Kubernetes 代码库的生态系统、代码或者第三方工具。例如,Kubernete 的一个新特性可以被*下游(downstream)* 应用采用,以提升它们的功能性。 +* 在 **GitHub** 或 **git** 中:约定用*下游(downstream)* 表示分支代码库,源代码库被认为是*上游(upstream)*。 + diff --git a/content/zh/docs/reference/glossary/dynamic-volume-provisioning.md b/content/zh/docs/reference/glossary/dynamic-volume-provisioning.md new file mode 100755 index 0000000000000..4f53bbef9d175 --- /dev/null +++ b/content/zh/docs/reference/glossary/dynamic-volume-provisioning.md @@ -0,0 +1,44 @@ +--- +title: 动态卷供应 +id: dynamicvolumeprovisioning +date: 2018-04-12 +full_link: /docs/concepts/storage/dynamic-provisioning +short_description: > + 允许用户请求自动创建存储卷。 + +aka: +tags: +- core-object +- storage +--- + + + + + + 允许用户请求自动创建存储 {{< glossary_tooltip text="卷" term_id="volume" >}}。 + + + + + +动态供应让集群管理员无需再预先供应存储。相反,它通过用户请求自动地供应存储。 +动态卷供应是基于 API 对象 {{< glossary_tooltip text="StorageClass" term_id="storage-class" >}} 的,StorageClass 可以引用 {{< glossary_tooltip text="卷插件(Volume Plugin)" term_id="volume-plugin" >}} 提供的 {{< glossary_tooltip text="卷(Volume)" term_id="volume" >}} ,也可以引用传递给卷插件(Volume Plugin)的参数集。 diff --git a/content/zh/docs/reference/glossary/etcd.md b/content/zh/docs/reference/glossary/etcd.md new file mode 100644 index 0000000000000..916fa44122ea7 --- /dev/null +++ b/content/zh/docs/reference/glossary/etcd.md @@ -0,0 +1,43 @@ +--- +title: etcd +id: etcd +date: 2018-04-12 +full_link: /docs/tasks/administer-cluster/configure-upgrade-etcd/ +short_description: > + etcd 是兼具一致性和高可用性的键值数据库,用作保存 Kubernetes 所有集群数据的后台数据库。 + +aka: +tags: +- architecture +- storage +--- + + + + + +etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。 + + + + + +您的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划。要了解 etcd 更深层次的信息,请参考 [etcd 文档](https://github.com/coreos/etcd/blob/master/Documentation/docs.md)。 diff --git a/content/zh/docs/reference/glossary/flexvolume.md b/content/zh/docs/reference/glossary/flexvolume.md new file mode 100644 index 0000000000000..5cb6b7b9e4ae2 --- /dev/null +++ b/content/zh/docs/reference/glossary/flexvolume.md @@ -0,0 +1,51 @@ +--- +title: Flexvolume +id: flexvolume +date: 2018-06-25 +full_link: /docs/concepts/storage/volumes/#flexvolume +short_description: > + Flexvolume 是创建 out-of-tree 卷插件的一种接口。 {{< glossary_tooltip text="容器存储接口(CSI)" term_id="csi" >}} 是比 Flexvolume 更新的接口,它解决了 Flexvolumes 的一些问题。 + + +aka: +tags: +- storage +--- + + + + Flexvolume 是创建 out-of-tree 卷插件的一种接口。 {{< glossary_tooltip text="容器存储接口(CSI)" term_id="csi" >}} 是比 Flexvolume 更新的接口,它解决了 Flexvolume 的一些问题。 + + + + + +Flexvolume 允许用户编写自己的驱动程序,并在 Kubernetes 中加入对用户自己的数据卷的支持。 +FlexVolume 驱动程序的二进制文件和依赖项必须安装在主机上。这需要 root 权限。 +如果可能的话,SIG Storage 建议实现 {{< glossary_tooltip text="CSI" term_id="csi" >}} 驱动程序,因为它解决了 Flexvolumes 的限制。 + + + +* [Kubernetes 文档中的 Flexvolume](/docs/concepts/storage/volumes/#flexvolume) +* [更多关于 Flexvolumes 的信息](https://github.com/kubernetes/community/blob/master/contributors/devel/flexvolume.md) +* [存储供应商的卷插件 FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md) diff --git a/content/zh/docs/reference/glossary/helm-chart.md b/content/zh/docs/reference/glossary/helm-chart.md new file mode 100755 index 0000000000000..d76c6a7906180 --- /dev/null +++ b/content/zh/docs/reference/glossary/helm-chart.md @@ -0,0 +1,43 @@ +--- +title: Helm Chart +id: helm-chart +date: 2018-04-12 +full_link: https://github.com/kubernetes/helm/blob/master/docs/charts.md +short_description: > + Helm Chart 是一组预先配置的 Kubernetes 资源所构成的包,可以使用 Helm 工具对其进行管理。 + +aka: +tags: +- tool +--- + + + + + +Helm Chart 是一组预先配置的 Kubernetes 资源所构成的包,可以使用 Helm 工具对其进行管理。 + + + + + +Chart 提供了一种可重现的用来创建和共享 Kubernetes 应用的方法。 +单个 Chart 可用来部署简单的系统(例如一个 memcached Pod),也可以用来部署复杂的系统(例如包含 HTTP 服务器、数据库、缓存等组件的完整 Web 应用堆栈)。 diff --git a/content/zh/docs/reference/glossary/horizontal-pod-autoscaler.md b/content/zh/docs/reference/glossary/horizontal-pod-autoscaler.md new file mode 100755 index 0000000000000..663ebd26c82b2 --- /dev/null +++ b/content/zh/docs/reference/glossary/horizontal-pod-autoscaler.md @@ -0,0 +1,37 @@ +--- +title: Pod 水平自动扩缩器 +id: horizontal-pod-autoscaler +date: 2018-04-12 +full_link: /docs/tasks/run-application/horizontal-pod-autoscale/ +short_description: > + Pod 水平自动扩缩器(Horizontal Pod Autoscaler)是一种 API 资源,它根据目标 CPU 利用率或自定义度量目标扩缩 Pod 副本的数量。 + +aka: +tags: +- operation +--- + + + + Pod 水平自动扩缩器(Horizontal Pod Autoscaler)是一种 API 资源,它根据目标 CPU 利用率或自定义度量目标扩缩 Pod 副本的数量。 + + + + + +HPA 通常用于 {{< glossary_tooltip text="Replication Controllers" term_id="replication-controller" >}}、{{< glossary_tooltip text="Deployments" term_id="deployment" >}} 或者 Replica Sets 上。HPA 不能用于不支持扩缩的对象,例如 {{< glossary_tooltip text="DaemonSets" term_id="daemonset" >}}。 diff --git a/content/zh/docs/reference/glossary/image.md b/content/zh/docs/reference/glossary/image.md new file mode 100755 index 0000000000000..1fc7db55e5165 --- /dev/null +++ b/content/zh/docs/reference/glossary/image.md @@ -0,0 +1,42 @@ +--- +title: 镜像 +id: image +date: 2018-04-12 +full_link: +short_description: > + 镜像是保存的容器实例,它打包了应用运行所需的一组软件。 + +aka: +tags: +- fundamental +--- + + + + + +镜像是保存的容器实例,它打包了应用运行所需的一组软件。 + + + + + +镜像是软件打包的一种方式,可以将镜像存储在容器镜像仓库、拉取到本地系统并作为应用来运行。 +镜像中包含的元数据指明了运行什么可执行程序、是由谁构建的以及其他信息。 diff --git a/content/zh/docs/reference/glossary/index.md b/content/zh/docs/reference/glossary/index.md new file mode 100755 index 0000000000000..6fc5f767f3dcd --- /dev/null +++ b/content/zh/docs/reference/glossary/index.md @@ -0,0 +1,23 @@ +--- +approvers: +- chenopis +- abiogenesis-now +title: 标准化词汇表 +layout: glossary +noedit: true +default_active_tag: fundamental +weight: 5 +--- + + diff --git a/content/zh/docs/reference/glossary/ingress.md b/content/zh/docs/reference/glossary/ingress.md new file mode 100644 index 0000000000000..806dec752d49e --- /dev/null +++ b/content/zh/docs/reference/glossary/ingress.md @@ -0,0 +1,46 @@ +--- +title: Ingress +id: ingress +date: 2018-04-12 +full_link: /docs/concepts/services-networking/ingress/ +short_description: > + Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。 + +aka: +tags: +- networking +- architecture +- extension +--- + + + + + + Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。 + + + + + +Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。 + diff --git a/content/zh/docs/reference/glossary/init-container.md b/content/zh/docs/reference/glossary/init-container.md new file mode 100755 index 0000000000000..cf8cead312a7f --- /dev/null +++ b/content/zh/docs/reference/glossary/init-container.md @@ -0,0 +1,41 @@ +--- +title: 初始化容器 +id: init-container +date: 2018-04-12 +full_link: +short_description: > + 应用容器运行前必须先运行完成的一个或多个初始化容器。 + +aka: +tags: +- fundamental +--- + + + + + + 应用容器运行前必须先运行完成的一个或多个初始化容器。 + + + + + +初始化(init)容器像常规应用容器一样,只有一点不同:初始化(init)容器必须在应用容器启动前运行完成。Init 容器的运行顺序:一个初始化(init)容器必须在下一个初始化(init)容器开始前运行完成。 diff --git a/content/zh/docs/reference/glossary/istio.md b/content/zh/docs/reference/glossary/istio.md new file mode 100755 index 0000000000000..58c4cfffcc482 --- /dev/null +++ b/content/zh/docs/reference/glossary/istio.md @@ -0,0 +1,45 @@ +--- +title: Istio +id: istio +date: 2018-04-12 +full_link: https://istio.io/docs/concepts/what-is-istio/overview.html +short_description: > + Istio 是个开放平台(非 Kubernetes 特有),提供了一种统一的方式来集成微服务、管理流量、实施策略和汇总度量数据。 +aka: +tags: +- networking +- architecture +- extension +--- + + + + + +Istio 是个开放平台(非 Kubernetes 特有),提供了一种统一的方式来集成微服务、管理流量、实施策略和汇总度量数据。 + + + + + +添加 Istio 时不需要修改应用代码。它是基础设施的一层,介于服务和网络之间。当它和服务的 Deployment 相结合时,就构成了通常所谓的服务网格(Service Mesh)。Istio 的控制面抽象掉了底层的集群管理平台,这一集群管理平台可以是 Kubernetes、Mesosphere 等。 + diff --git a/content/zh/docs/reference/glossary/job.md b/content/zh/docs/reference/glossary/job.md new file mode 100755 index 0000000000000..8ce421f2804fb --- /dev/null +++ b/content/zh/docs/reference/glossary/job.md @@ -0,0 +1,45 @@ +--- +title: Job +id: job +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/jobs-run-to-completion +short_description: > + Job 是需要运行完成的确定性的或批量的任务。 + +aka: +tags: +- fundamental +- core-object +- workload +--- + + + + + + Job 是需要运行完成的确定性的或批量的任务。 + + + + + +Job 创建一个或多个 {{< glossary_tooltip term_id="Pod" >}} 对象,并确保指定数量的 Pod 成功终止。随着各 Pod 成功结束,Job 会跟踪记录成功完成的个数。 diff --git a/content/zh/docs/reference/glossary/kops.md b/content/zh/docs/reference/glossary/kops.md new file mode 100755 index 0000000000000..c1024390e7f45 --- /dev/null +++ b/content/zh/docs/reference/glossary/kops.md @@ -0,0 +1,63 @@ +--- +title: Kops +id: kops +date: 2018-04-12 +full_link: /docs/getting-started-guides/kops/ +short_description: > + kops 是一个命令行工具,可以帮助您创建、销毁、升级和维护生产级,高可用性的 Kubernetes 集群。注意:官方仅支持 AWS,GCE 和 VMware vSphere 的支持还处于 alpha* 阶段。 + +aka: +tags: +- tool +- operation +--- + + + + + +kops 是一个命令行工具,可以帮助您创建、销毁、升级和维护生产级,高可用性的 Kubernetes 集群。*注意:官方仅支持 AWS,GCE 和 VMware vSphere 的支持还处于 alpha 阶段*。 + + + + + +`kops` 为您的集群提供了: + + * 全自动化安装 + * 基于 DNS 的集群标识 + * 自愈功能:所有组件都在自动伸缩组(Auto-Scaling Groups)中运行 + * 有限的操作系统支持 (推荐使用 Debian,支持 Ubuntu 16.04,试验性支持 CentOS & RHEL) + * 高可用 (HA) 支持 + * 直接提供或者生成 Terraform 清单文件的能力 + + + +您也可以将自己的集群作为一个构造块,使用 {{< glossary_tooltip term_id="kubeadm" >}} 构造集群。`kops` 是建立在 kubeadm 之上的。 diff --git a/content/zh/docs/reference/glossary/kube-apiserver.md b/content/zh/docs/reference/glossary/kube-apiserver.md new file mode 100755 index 0000000000000..c2d0e8a9eb56c --- /dev/null +++ b/content/zh/docs/reference/glossary/kube-apiserver.md @@ -0,0 +1,44 @@ +--- +title: kube-apiserver +id: kube-apiserver +date: 2018-04-12 +full_link: /docs/reference/generated/kube-apiserver/ +short_description: > + 主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端。 + +aka: +tags: +- architecture +- fundamental +--- + + + + + +主节点上负责提供 Kubernetes API 服务的组件;它是 Kubernetes 控制面的前端。 + + + + + +kube-apiserver 在设计上考虑了水平扩缩的需要。 +换言之,通过部署多个实例可以实现扩缩。 +参见[构造高可用集群](/docs/admin/high-availability/)。 + diff --git a/content/zh/docs/reference/glossary/kube-controller-manager.md b/content/zh/docs/reference/glossary/kube-controller-manager.md new file mode 100755 index 0000000000000..c24234e501134 --- /dev/null +++ b/content/zh/docs/reference/glossary/kube-controller-manager.md @@ -0,0 +1,39 @@ +--- +title: kube-controller-manager +id: kube-controller-manager +date: 2018-04-12 +full_link: /docs/reference/generated/kube-controller-manager/ +short_description: > + 主节点上运行控制器的组件。 + +aka: +tags: +- architecture +- fundamental +--- + + + + +在主节点上运行{{< glossary_tooltip text="控制器" term_id="controller" >}}的组件。 + + + +从逻辑上讲,每个{{< glossary_tooltip text="控制器" term_id="controller" >}}都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。 + diff --git a/content/zh/docs/reference/glossary/kube-proxy.md b/content/zh/docs/reference/glossary/kube-proxy.md new file mode 100755 index 0000000000000..64a3626920f24 --- /dev/null +++ b/content/zh/docs/reference/glossary/kube-proxy.md @@ -0,0 +1,43 @@ +--- +title: kube-proxy +id: kube-proxy +date: 2018-04-12 +full_link: /docs/reference/generated/kube-proxy +short_description: > + `kube-proxy` 是集群中每个节点上运行的网络代理。 + +aka: +tags: +- fundamental +- core-object +--- + + + + + +`kube-proxy` 是集群中每个节点上运行的网络代理。 + + + + + +`kube-proxy` 负责转发请求。`kube-proxy` 能够提供 TCP 和 UDP 的流转发,也可为一组后端功能点提供轮转式 TCP 和 UDP 转发。 diff --git a/content/zh/docs/reference/glossary/kube-scheduler.md b/content/zh/docs/reference/glossary/kube-scheduler.md new file mode 100755 index 0000000000000..67d82d98d7523 --- /dev/null +++ b/content/zh/docs/reference/glossary/kube-scheduler.md @@ -0,0 +1,42 @@ +--- +title: kube-scheduler +id: kube-scheduler +date: 2018-04-12 +full_link: /docs/reference/generated/kube-scheduler/ +short_description: > + 主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。 + +aka: +tags: +- architecture +- scheduler +--- + + + + + +主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。 + + + + + +调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。 diff --git a/content/zh/docs/reference/glossary/kubeadm.md b/content/zh/docs/reference/glossary/kubeadm.md new file mode 100644 index 0000000000000..3d7ce11b59db4 --- /dev/null +++ b/content/zh/docs/reference/glossary/kubeadm.md @@ -0,0 +1,43 @@ +--- +title: Kubeadm +id: kubeadm +date: 2018-04-12 +full_link: /docs/admin/kubeadm/ +short_description: > + 用来快速安装 Kubernetes 并搭建安全稳定的集群的工具。 + +aka: +tags: +- tool +- operation +--- + + + + + + 用来快速安装 Kubernetes 并搭建安全稳定的集群的工具。 + + + + + +您可以使用 kubeadm 安装控制面和工作节点组件。 diff --git a/content/zh/docs/reference/glossary/kubectl.md b/content/zh/docs/reference/glossary/kubectl.md new file mode 100755 index 0000000000000..2c8bde22eb846 --- /dev/null +++ b/content/zh/docs/reference/glossary/kubectl.md @@ -0,0 +1,43 @@ +--- +title: Kubectl +id: kubectl +date: 2018-04-12 +full_link: /docs/user-guide/kubectl-overview/ +short_description: > + kubectl 是用来和 Kubernetes API 服务器进行通信的命令行工具。 + +aka: +tags: +- tool +- fundamental +--- + + + + + + kubectl 是用来和 {{< glossary_tooltip text="Kubernetes API" term_id="kubernetes-api" >}} 服务器进行通信的命令行工具。 + + + + + +您可以使用 kubectl 创建、检查、更新和删除 Kubernetes 对象。 diff --git a/content/zh/docs/reference/glossary/kubelet.md b/content/zh/docs/reference/glossary/kubelet.md new file mode 100755 index 0000000000000..c561109b6e89c --- /dev/null +++ b/content/zh/docs/reference/glossary/kubelet.md @@ -0,0 +1,40 @@ +--- +title: Kubelet +id: kubelet +date: 2018-04-12 +full_link: /docs/reference/generated/kubelet +short_description: > + 一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。 + +aka: +tags: +- fundamental +- core-object +--- + + +一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。 + + + + + +kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。kubelet 不会管理不是由 Kubernetes 创建的容器。 diff --git a/content/zh/docs/reference/glossary/kubernetes-api.md b/content/zh/docs/reference/glossary/kubernetes-api.md new file mode 100755 index 0000000000000..fc1dbeac6a0e8 --- /dev/null +++ b/content/zh/docs/reference/glossary/kubernetes-api.md @@ -0,0 +1,47 @@ +--- +title: Kubernetes API +id: kubernetes-api +date: 2018-04-12 +full_link: /docs/concepts/overview/kubernetes-api/ +short_description: > + Kubernetes API 是通过 RESTful 接口提供 Kubernetes 功能服务并负责集群状态存储的应用程序。 + +aka: +tags: +- fundamental +- architecture +--- + + + + + +Kubernetes API 是通过 RESTful 接口提供 Kubernetes 功能服务并负责集群状态存储的应用程序。 + + + + + +Kubernetes 资源和"意向记录"都是作为 API 对象储存的,并可以通过对 API 的 RESTful 调用进行修改。 +API 允许以声明方式管理配置。 +用户可以直接和 Kubernetes API 交互,也可以通过 `kubectl` 这样的工具进行交互。 +核心的 Kubernetes API 是很灵活的,可以扩展以支持定制资源。 + diff --git a/content/zh/docs/reference/glossary/label.md b/content/zh/docs/reference/glossary/label.md new file mode 100755 index 0000000000000..6201aaeb2999d --- /dev/null +++ b/content/zh/docs/reference/glossary/label.md @@ -0,0 +1,41 @@ +--- +title: 标签 +id: label +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/labels +short_description: > + 用来为对象设置可标识的属性标记;这些标记对用户而言是有意义且重要的。 + +aka: +tags: +- fundamental +--- + + + + + +用来为对象设置可标识的属性标记;这些标记对用户而言是有意义且重要的。 + + + + + +标签是一些关联到 {{< glossary_tooltip text="Pods" term_id="pod" >}} 这类对象上的键值对。 +它们通常用来组织和选择对象子集。 + diff --git a/content/zh/docs/reference/glossary/managed-service.md b/content/zh/docs/reference/glossary/managed-service.md new file mode 100755 index 0000000000000..fb7d5440c99d6 --- /dev/null +++ b/content/zh/docs/reference/glossary/managed-service.md @@ -0,0 +1,42 @@ +--- +title: 托管服务 +id: managed-service +date: 2018-04-12 +full_link: +short_description: > + 由第三方供应商负责维护的一种软件产品。 + +aka: +tags: +- extension +--- + + + + + +由第三方供应商负责维护的一种软件产品。 + + + + + +托管服务的一些例子有 AWS EC2、Azure SQL 数据库和 GCP Pub/Sub 等, +不过它们也可以是可以被某应用使用的任何软件交付件。 +[服务目录](/docs/concepts/service-catalog/)提供了一种方法用来列举、供应和绑定到 +{{< glossary_tooltip text="服务代理商" term_id="service-broker" >}}所提供的托管服务。 diff --git a/content/zh/docs/reference/glossary/member.md b/content/zh/docs/reference/glossary/member.md new file mode 100644 index 0000000000000..57e7cac386e86 --- /dev/null +++ b/content/zh/docs/reference/glossary/member.md @@ -0,0 +1,42 @@ +--- +title: 成员 +id: member +date: 2018-04-12 +full_link: +short_description: > + K8s 社区中持续活跃的贡献者。 + +aka: +tags: +- community +--- + + + + + + K8s 社区中持续活跃的贡献者。 + + + + + +可以将问题单(issue)和 PR 指派给成员,成员也可以通过 GitHub 小组加入 {{< glossary_tooltip text="特别兴趣小组 (SIGs)" term_id="sig" >}}。针对成员所提交的 PR,系统自动运行提交前测试。成员应该是持续活跃的社区贡献者。 + diff --git a/content/zh/docs/reference/glossary/minikube.md b/content/zh/docs/reference/glossary/minikube.md new file mode 100755 index 0000000000000..e88e513ba440f --- /dev/null +++ b/content/zh/docs/reference/glossary/minikube.md @@ -0,0 +1,43 @@ +--- +title: Minikube +id: minikube +date: 2018-04-12 +full_link: /docs/getting-started-guides/minikube/ +short_description: > + Minikube 是用来在本地运行 Kubernetes 的一种工具。 + +aka: +tags: +- fundamental +- tool +--- + + + + + +Minikube 是用来在本地运行 Kubernetes 的一种工具。 + + + + + +Minikube 在用户计算机上的一个虚拟机内运行单节点 Kubernetes 集群。 diff --git a/content/zh/docs/reference/glossary/name.md b/content/zh/docs/reference/glossary/name.md new file mode 100755 index 0000000000000..05532e09279c2 --- /dev/null +++ b/content/zh/docs/reference/glossary/name.md @@ -0,0 +1,41 @@ +--- +title: 名称 +id: name +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/names +short_description: > + 客户端提供的字符串,用来指代资源 URL 中的对象,如 `/api/v1/pods/some-name`。 + +aka: +tags: +- fundamental +--- + + + + + +客户端提供的字符串,用来指代资源 URL 中的对象,如 `/api/v1/pods/some-name`。 + + + + + +对给定资源类型 (kind) 而言,同一时刻只能有一个对象使用给定的名称。不过,如果该对象被删除,则可以使用同一名称创建新新对象。 diff --git a/content/zh/docs/reference/glossary/namespace.md b/content/zh/docs/reference/glossary/namespace.md new file mode 100644 index 0000000000000..42019215cfdcb --- /dev/null +++ b/content/zh/docs/reference/glossary/namespace.md @@ -0,0 +1,41 @@ +--- +title: 命名空间 +id: namespace +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/namespaces +short_description: > + 命名空间是 Kubernetes 为了在同一物理集群上支持多个虚拟集群而使用的一种抽象。 + +aka: +tags: +- fundamental +--- + + + + + +命名空间是 Kubernetes 为了在同一物理集群上支持多个虚拟集群而使用的一种抽象。 + + + + + +命名空间用来组织集群中对象,并为集群资源划分提供了一种方法。同一命名空间内的资源名称必须唯一,但跨命名空间时不作要求。 diff --git a/content/zh/docs/reference/glossary/network-policy.md b/content/zh/docs/reference/glossary/network-policy.md new file mode 100755 index 0000000000000..25269bcc05472 --- /dev/null +++ b/content/zh/docs/reference/glossary/network-policy.md @@ -0,0 +1,44 @@ +--- +title: 网络策略 +id: network-policy +date: 2018-04-12 +full_link: /docs/concepts/services-networking/network-policies/ +short_description: > + 网络策略是一种规范,规定了允许 Pod 组之间、Pod 与其他网络端点之间以怎样的方式进行通信。 + +aka: +tags: +- networking +- architecture +- extension +--- + + + +网络策略是一种规范,规定了允许 Pod 组之间、Pod 与其他网络端点之间以怎样的方式进行通信。 + + + + + +网络策略帮助您声明式地配置允许哪些 Pod 之间接、哪些命名空间之间允许进行通信,并具体配置了哪些端口号来执行各个策略。`NetworkPolicy` 资源使用标签来选择 Pod,并定义了所选 Pod 可以接受什么样的流量。网络策略由网络提供商提供的并被 Kubernetes 支持的网络插件实现。请注意,当没有控制器实现网络资源时,创建网络资源将不会生效。 diff --git a/content/zh/docs/reference/glossary/node.md b/content/zh/docs/reference/glossary/node.md new file mode 100755 index 0000000000000..d1756799b7784 --- /dev/null +++ b/content/zh/docs/reference/glossary/node.md @@ -0,0 +1,43 @@ +--- +title: 节点 +id: node +date: 2018-04-12 +full_link: /docs/concepts/architecture/nodes/ +short_description: > + Kubernetes 中的工作机器称作节点。 + +aka: +tags: +- fundamental +--- + + + + + +Kubernetes 中的工作机器称作节点。 + + + + + +工作机器可以是虚拟机也可以是物理机,取决于集群的配置。 +其上部署了运行 {{< glossary_tooltip text="Pods" term_id="pod" >}} 所必需的{{< glossary_tooltip text="服务" term_id="service" >}}, +并由主控组件来管理。 +节点上的{{< glossary_tooltip text="服务" term_id="service" >}}包括 Docker、kubelet 和 kube-proxy。 + diff --git a/content/zh/docs/reference/glossary/persistent-volume-claim.md b/content/zh/docs/reference/glossary/persistent-volume-claim.md new file mode 100755 index 0000000000000..00fc0c563f40f --- /dev/null +++ b/content/zh/docs/reference/glossary/persistent-volume-claim.md @@ -0,0 +1,39 @@ +--- +title: 持久卷申领 +id: persistent-volume-claim +date: 2018-04-12 +full_link: /docs/concepts/storage/persistent-volumes/ +short_description: > + 声明在持久卷中定义的存储资源,以便可以将其挂载为容器中的卷。 + +aka: +tags: +- core-object +- storage +--- + + + + +申领持久卷中定义的存储资源,以便可以将其挂载为容器中的卷。 + + + + +指定存储的数量,如何访问存储(只读、读写或独占)以及如何回收存储(保留、回收或删除)。存储本身的详细信息在 PersistentVolume 规范中。 diff --git a/content/zh/docs/reference/glossary/persistent-volume.md b/content/zh/docs/reference/glossary/persistent-volume.md new file mode 100644 index 0000000000000..d2364a6f8a8b2 --- /dev/null +++ b/content/zh/docs/reference/glossary/persistent-volume.md @@ -0,0 +1,48 @@ +--- +title: 持久卷 +id: persistent-volume +date: 2018-04-12 +full_link: /docs/concepts/storage/persistent-volumes/ +short_description: > + 持久卷是代表集群中一块存储空间的 API 对象。 它是通用的、可插拔的、并且不受单个 Pod 生命周期约束的持久化资源。 + +aka: +tags: +- core-object +- storage +--- + + + + + +持久卷是代表集群中一块存储空间的 API 对象。 它是通用的、可插拔的、并且不受单个 Pod 生命周期约束的持久化资源。 + + + + + +持久卷(PersistentVolumes,PV)提供了一个 API,该 API 对存储的供应方式细节进行抽象,令其与使用方式相分离。 +在提前创建存储(静态供应)的场景中,PV 可以直接使用。 +在按需提供存储(动态供应)的场景中,需要使用 PersistentVolumeClaims (PVCs)。 + diff --git a/content/zh/docs/reference/glossary/platform-developer.md b/content/zh/docs/reference/glossary/platform-developer.md new file mode 100755 index 0000000000000..0cc10ac633bc9 --- /dev/null +++ b/content/zh/docs/reference/glossary/platform-developer.md @@ -0,0 +1,42 @@ +--- +title: 平台开发者 +id: platform-developer +date: 2018-04-12 +full_link: +short_description: > + 定制 Kubernetes 平台以满足自己的项目需求的人。 + +aka: +tags: +- user-type +--- + + + + + + 定制 Kubernetes 平台以满足自己的项目需求的人。 + + + + + +例如,平台开发人员可以使用[定制资源](/docs/concepts/api-extension/custom-resources/)或[使用汇聚层扩展 Kubernetes API](/docs/concepts/api-extension/apiserver-aggregation/) 来为其 Kubernetes 实例增加功能,特别是为其应用程序添加功能。一些平台开发人员也是 Kubrenetes {{< glossary_tooltip text="贡献者" term_id="contributor" >}},他们会开发贡献给 Kubernetes 社区的扩展;另一些则开发封闭源代码的商业扩展或用于特定功能的扩展。 + diff --git a/content/zh/docs/reference/glossary/pod-security-policy.md b/content/zh/docs/reference/glossary/pod-security-policy.md new file mode 100644 index 0000000000000..e9937009cde94 --- /dev/null +++ b/content/zh/docs/reference/glossary/pod-security-policy.md @@ -0,0 +1,46 @@ +--- +title: Pod 安全策略 +id: pod-security-policy +date: 2018-04-12 +full_link: /docs/concepts/policy/pod-security-policy/ +short_description: > + 为 Pod 的创建和更新操作启用细粒度的授权。 + +aka: +tags: +- core-object +- fundamental +--- + + + + + +为 Pod 的创建和更新操作启用细粒度的授权。 + + + + + +Pod 安全策略是集群级别的资源,它控制着 Pod 规约中的安全性敏感的内容。 +`PodSecurityPolicy`对象定义了一组条件以及相关字段的默认值,Pod 运行时必须满足这些条件。Pod 安全策略控制实现上体现为一个可选的准入控制器。 + + diff --git a/content/zh/docs/reference/glossary/pod.md b/content/zh/docs/reference/glossary/pod.md new file mode 100755 index 0000000000000..d8fcbb4cee452 --- /dev/null +++ b/content/zh/docs/reference/glossary/pod.md @@ -0,0 +1,43 @@ +--- +title: Pod +id: pod +date: 2018-04-12 +full_link: /docs/concepts/workloads/pods/pod-overview/ +short_description: > + Pod 是 Kubernetes 的原子对象。Pod 表示您的集群上一组正在运行的容器。 + +aka: +tags: +- core-object +- fundamental +--- + + + + + + Pod 是 Kubernetes 的原子对象。Pod 表示您的集群上一组正在运行的{{< glossary_tooltip text="容器" term_id="container" >}}。 + + + + + +通常创建 Pod 是为了运行单个主容器。Pod 还可以运行可选的挂斗(sidecar)容器,以添加诸如日志记录之类的补充特性。通常用 {{< glossary_tooltip term_id="deployment" >}} 来管理 Pod。 diff --git a/content/zh/docs/reference/glossary/podpreset.md b/content/zh/docs/reference/glossary/podpreset.md new file mode 100755 index 0000000000000..3c5789de6df08 --- /dev/null +++ b/content/zh/docs/reference/glossary/podpreset.md @@ -0,0 +1,40 @@ +--- +title: PodPreset +id: podpreset +date: 2018-04-12 +full_link: +short_description: > + PodPreset 是一种 API 对象,在创建 Pod 时将诸如 Secret、卷挂载和环境变量之类的信息注入到该 Pod 中。 + +aka: +tags: +- operation +--- + + + + +PodPreset 是一种 API 对象,在创建 Pod 时将诸如 Secret、卷挂载和环境变量之类的信息注入到该 Pod 中。 + + + + + +此 API 对象使用标准选择器选择 Pod 并向其中注入信息。这允许 podspec 定义是非特定的,从而将 podspec 与环境特定的配置解耦。 diff --git a/content/zh/docs/reference/glossary/quantity.md b/content/zh/docs/reference/glossary/quantity.md new file mode 100644 index 0000000000000..70d5a95ffab77 --- /dev/null +++ b/content/zh/docs/reference/glossary/quantity.md @@ -0,0 +1,60 @@ +--- +title: 数量 +id: quantity +date: 2018-08-07 +full_link: +short_description: > + 使用 SI 后缀的小数或大数的整数表示。 + +aka: +tags: +- core-object +--- + + + + +数量是使用紧凑的整数表示法的小数或大数的表示,并带有国际计量单位制(SI)后缀。 +小数用 milli 单位表示,而大数用 kilo、mega 或 giga 单位表示。 + +例如,数字 `1.5` 表示为`1500m`, +而数字`1000`表示为`1k`,`1000000`表示为`1M`。 +您还可以指定二进制表示法后缀; 数字 2048 可以写成`2Ki`。 + +公认的十进制(10的幂)单位是 `m`(milli)、`k`(kilo, +有意小写)、`M`(mega),`G`(giga)、`T`(terra)、`P`(peta)、 +`E`(exa)。 + +公认的二进制(2的幂)单位是 `Ki` (kibi)、 `Mi` (mebi)、`Gi` (gibi)、 +`Ti` (tebi)、 `Pi` (pebi)、 `Ei` (exbi)。 + + diff --git a/content/zh/docs/reference/glossary/rbac.md b/content/zh/docs/reference/glossary/rbac.md new file mode 100755 index 0000000000000..6f045ed9d0171 --- /dev/null +++ b/content/zh/docs/reference/glossary/rbac.md @@ -0,0 +1,43 @@ +--- +title: RBAC(基于角色的访问控制) +id: rbac +date: 2018-04-12 +full_link: /docs/reference/access-authn-authz/rbac/ +short_description: > + 管理授权决策,允许管理员通过 Kubernetes API 动态配置访问策略。 + +aka: +tags: +- security +- fundamental +--- + + + + +管理授权决策,允许管理员通过 {{< glossary_tooltip text="Kubernetes API" term_id="kubernetes-api" >}} 动态配置访问策略。 + + + + +RBAC 使用 *角色* (包含权限规则)和 *角色绑定* (将角色中定义的权限授予一组用户)。 + + diff --git a/content/zh/docs/reference/glossary/replica-set.md b/content/zh/docs/reference/glossary/replica-set.md new file mode 100755 index 0000000000000..5f394133b6b0c --- /dev/null +++ b/content/zh/docs/reference/glossary/replica-set.md @@ -0,0 +1,45 @@ +--- +title: ReplicaSet +id: replica-set +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/replicaset/ +short_description: > + ReplicaSet 是下一代副本控制器。 + +aka: +tags: +- fundamental +- core-object +- workload +--- + + + + + +ReplicaSet 是下一代副本控制器。 + + + + + +ReplicaSet 就像 ReplicationController 那样,确保一次运行指定数量的 Pod 副本。ReplicaSet 支持新的基于集合的选择器需求(在标签的用户指南中有相关描述),而副本控制器只支持基于等值的选择器需求。 diff --git a/content/zh/docs/reference/glossary/replication-controller.md b/content/zh/docs/reference/glossary/replication-controller.md new file mode 100644 index 0000000000000..8fd910e79997f --- /dev/null +++ b/content/zh/docs/reference/glossary/replication-controller.md @@ -0,0 +1,43 @@ +--- +title: Replication Controller +id: replication-controller +date: 2018-04-12 +full_link: +short_description: > + Replication Controller 是 Kubernetes 的一种服务,用来确保给定个数的 Pod 一直处于运行状态。 + +aka: +tags: +- workload +- core-object +--- + + + + + +Replication Controller 是 Kubernetes 的一种服务,用来确保给定个数的 Pod 一直处于运行状态。 + + + + + +Replication Controller 会基于设定值自动增删 Pod 的实例。如果 Pod 被误删除或者启动实例过多,Replication Controller 允许 Pod 的实例个数恢复到设定值。 diff --git a/content/zh/docs/reference/glossary/resource-quota.md b/content/zh/docs/reference/glossary/resource-quota.md new file mode 100755 index 0000000000000..c0f40f32340bf --- /dev/null +++ b/content/zh/docs/reference/glossary/resource-quota.md @@ -0,0 +1,47 @@ +--- +title: 资源配额 +id: resource-quota +date: 2018-04-12 +full_link: /docs/concepts/policy/resource-quotas/ +short_description: > + 资源配额提供了限制每个命名空间的资源消耗总和的约束。 + +aka: +tags: +- fundamental +- operation +- architecture +--- + + + + + +资源配额提供了限制每个 {{< glossary_tooltip text="命名空间" term_id="namespace">}} 的资源消耗总和的约束。 + + + + + +限制了命名空间中每种对象可以创建的数量,也限制了项目中可被资源对象利用的计算资源总数。 + + diff --git a/content/zh/docs/reference/glossary/reviewer.md b/content/zh/docs/reference/glossary/reviewer.md new file mode 100644 index 0000000000000..a181122927254 --- /dev/null +++ b/content/zh/docs/reference/glossary/reviewer.md @@ -0,0 +1,41 @@ +--- +title: 评审者 +id: reviewer +date: 2018-04-12 +full_link: +short_description: > + 评审者是负责评审项目的某部分代码以便提高代码质量和正确性的人。 + +aka: +tags: +- community +--- + + + + + + 评审者是负责评审项目的某部分代码以便提高代码质量和正确性的人。 + + + + + +评审者既要了解代码库又要了解软件工程规范。评审者状态是基于代码库的组成部分来设定的。 diff --git a/content/en/docs/reference/glossary/rkt.md b/content/zh/docs/reference/glossary/rkt.md similarity index 59% rename from content/en/docs/reference/glossary/rkt.md rename to content/zh/docs/reference/glossary/rkt.md index 165bce5406130..b3423f32ff90b 100644 --- a/content/en/docs/reference/glossary/rkt.md +++ b/content/zh/docs/reference/glossary/rkt.md @@ -11,8 +11,16 @@ tags: - security - tool --- + + - +一个安全的,基于标准的容器引擎。 + + + +rkt 是一个应用程序 {{}} 引擎,其中包含{{}} -原生方法,可插拔式执行环境, 和定义良好的展示模块。 rkt 允许用户在 Pod 和应用程序级别应用不同的配置。每个 Pod 都直接在经典的 Unix 进程模型中,在一个独立的隔离环境中执行。 diff --git a/content/zh/docs/reference/glossary/secret.md b/content/zh/docs/reference/glossary/secret.md new file mode 100755 index 0000000000000..a43dbb6ecefa0 --- /dev/null +++ b/content/zh/docs/reference/glossary/secret.md @@ -0,0 +1,45 @@ +--- +title: Secret +id: secret +date: 2018-04-12 +full_link: /docs/concepts/configuration/secret/ +short_description: > + Secret 用于存储敏感信息,如密码、OAuth 令牌和 SSH 密钥。 + +aka: +tags: +- core-object +- security +--- + + + + + + Secret 用于存储敏感信息,如密码、OAuth 令牌和 SSH 密钥。 + + + + + +Secret 允许用户对如何使用敏感信息进行更多的控制,并减少信息意外暴露的风险,包括静态[加密](/docs/tasks/administer-cluster/encrypt-data/#ensure-all-secrets-are-encrypted)。 +{{< glossary_tooltip text="Pod" term_id="pod" >}} 通过挂载卷中的文件的方式引用 Secret,或者通过 kubelet 为 pod 拉取镜像时引用。 +Secret 非常适合机密数据使用,而 [ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/) 适用于非机密数据。 diff --git a/content/zh/docs/reference/glossary/security-context.md b/content/zh/docs/reference/glossary/security-context.md new file mode 100755 index 0000000000000..31b99c635cec2 --- /dev/null +++ b/content/zh/docs/reference/glossary/security-context.md @@ -0,0 +1,43 @@ +--- +title: 安全上下文(Security Context) +id: security-context +date: 2018-04-12 +full_link: /docs/tasks/configure-pod-container/security-context/ +short_description: > + securityContext 字段定义 Pod 或容器的特权和访问控制设置,包括运行时 UID 和 GID。 + +aka: +tags: +- security +--- + + + + +securityContext 字段定义 Pod 或容器的特权和访问控制设置,包括运行时 UID 和 GID。 + + + + +{{< glossary_tooltip term_id="pod" >}} 或者容器中的 securityContext 字段(应用于所有容器)用于设置容器进程使用的用户(runAsUser)和组 (fsGroup)、权能字、特权设置和安全策略(SELinux/AppArmor/Seccomp)。 + + + + diff --git a/content/zh/docs/reference/glossary/selector.md b/content/zh/docs/reference/glossary/selector.md new file mode 100644 index 0000000000000..5a3e83ef0dfc2 --- /dev/null +++ b/content/zh/docs/reference/glossary/selector.md @@ -0,0 +1,42 @@ +--- +title: 选择算符 +id: selector +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/labels/ +short_description: > + 选择算符允许用户通过标签对一组资源对象进行筛选过滤。 + +aka: +tags: +- fundamental +--- + + + + + +选择算符允许用户通过标签对一组资源对象进行筛选过滤。 + + + + + +在查询资源列表时,选择算符可以通过 {{< glossary_tooltip text="标签" term_id="label" >}} 对资源进行过滤筛选。 + diff --git a/content/zh/docs/reference/glossary/service-account.md b/content/zh/docs/reference/glossary/service-account.md new file mode 100755 index 0000000000000..4dd29b301b128 --- /dev/null +++ b/content/zh/docs/reference/glossary/service-account.md @@ -0,0 +1,43 @@ +--- +title: 服务账户 +id: service-account +date: 2018-04-12 +full_link: /docs/tasks/configure-pod-container/configure-service-account/ +short_description: > + 为在 Pod 中运行的进程提供标识。 + +aka: +tags: +- fundamental +- core-object +--- + + + + +为在 {{< glossary_tooltip text="Pod" term_id="pod" >}} 中运行的进程提供标识。 + + + + +当 Pod 中的进程访问集群时,API 服务器将它们作为特定的服务帐户进行身份验证,例如 `default`。当您创建 Pod 时,如果您没有指定服务帐户,它将在相同的命名空间 {{< glossary_tooltip text="命名空间" term_id="namespace" >}} 中自动分配 default 服务账户。 + + diff --git a/content/zh/docs/reference/glossary/service-broker.md b/content/zh/docs/reference/glossary/service-broker.md new file mode 100755 index 0000000000000..8a017d127b5c7 --- /dev/null +++ b/content/zh/docs/reference/glossary/service-broker.md @@ -0,0 +1,42 @@ +--- +title: 服务代理(Service Broker) +id: service-broker +date: 2018-04-12 +full_link: +short_description: > + 由第三方提供并维护的一组托管服务的访问端点。 + +aka: +tags: +- extension +--- + + + + + +由第三方提供并维护的一组{{< glossary_tooltip text="托管服务" term_id="managed-service">}} 的访问端点。 + + + + + +{{< glossary_tooltip text="服务代理" term_id="service-broker">}}会实现 +[开放服务代理 API 规范](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md) +并为应用提供使用其托管服务的标准接口。 +[服务目录(Service Catalog)](/docs/concepts/service-catalog/)则提供一种方法,用来列举、供应和绑定服务代理商所提供的托管服务。 diff --git a/content/zh/docs/reference/glossary/service-catalog.md b/content/zh/docs/reference/glossary/service-catalog.md new file mode 100644 index 0000000000000..726aff57c2ef2 --- /dev/null +++ b/content/zh/docs/reference/glossary/service-catalog.md @@ -0,0 +1,43 @@ +--- +title: 服务目录 +id: service-catalog +date: 2018-04-12 +full_link: +short_description: > + 服务目录是一种扩展 API,它能让 Kubernetes 集群中运行的应用易于使用外部托管的软件服务,例如云供应商提供的数据仓库服务。 + + An extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider. +aka: +tags: +- extension +--- + + + + + +服务目录(Service Catalog)是一种扩展 API,它能让 Kubernetes 集群中运行的应用易于使用外部托管的的软件服务,例如云供应商提供的数据仓库服务。 + + + + + +服务目录可以检索、供应、和绑定由 {{< glossary_tooltip text="服务代理人(Service Brokers)" term_id="service-broker" >}} 提供的外部 {{< glossary_tooltip text="托管服务" term_id="managed-service" >}},而无需知道那些服务具体是怎样创建和托管的。 + diff --git a/content/zh/docs/reference/glossary/service.md b/content/zh/docs/reference/glossary/service.md new file mode 100755 index 0000000000000..6d2f3f007858b --- /dev/null +++ b/content/zh/docs/reference/glossary/service.md @@ -0,0 +1,43 @@ +--- +title: Service +id: service +date: 2018-04-12 +full_link: /docs/concepts/services-networking/service/ +short_description: > + Service 是一种 API 资源对象,它描述了应用的访问方式,例如包含一组 Pod 的应用如何进行访问,Service 还可以描述端口和负载均衡。 + +aka: +tags: +- fundamental +- core-object +--- + + + + + + Service 是一种 API 资源对象,它描述了应用的访问方式,例如包含一组 Pod 的应用如何进行访问,Service 还可以描述端口和负载均衡。 + + + + + +Service 的接入点可以是集群内部的也可以是集群外部的。 diff --git a/content/zh/docs/reference/glossary/sig.md b/content/zh/docs/reference/glossary/sig.md new file mode 100755 index 0000000000000..a42a15b0b1c75 --- /dev/null +++ b/content/zh/docs/reference/glossary/sig.md @@ -0,0 +1,48 @@ +--- +title: SIG (特别兴趣小组) +id: sig +date: 2018-04-12 +full_link: https://github.com/kubernetes/community/blob/master/sig-list.md#master-sig-list +short_description: > + 共同管理大范畴 Kubernetes 开源项目中某组件或方面的一组社区成员。 + +aka: +tags: +- community +--- + + + + + +共同管理大范畴 Kubernetes 开源项目中某组件或方面的一组{{< glossary_tooltip text="社区成员" term_id="member" >}}。 + + + + + +SIG 中的成员对推进某个领域(如体系结构、API 机制构件或者文档)具有相同的兴趣。 +SIGs 必须遵从 [SIG Governance](https://github.com/kubernetes/community/blob/master/sig-governance.md) 的规定, +不过可以有自己的贡献策略以及通信渠道(方式)。 + +更多的详细信息可参阅 [kubernetes/community](https://github.com/kubernetes/community) 仓库以及 +[SIGs 和工作组(Working Groups)](https://github.com/kubernetes/community/blob/master/sig-list.md)的最新列表。 + diff --git a/content/zh/docs/reference/glossary/statefulset.md b/content/zh/docs/reference/glossary/statefulset.md new file mode 100644 index 0000000000000..ff63c63ce16b7 --- /dev/null +++ b/content/zh/docs/reference/glossary/statefulset.md @@ -0,0 +1,49 @@ +--- +title: StatefulSet +id: statefulset +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/statefulset/ +short_description: > + StatefulSet 用来管理 Deployment 和伸缩一组 Pod,并且能为这些 Pod 提供*序号和唯一性保证*。 +aka: +tags: +- fundamental +- core-object +- workload +- storage +--- + + + + StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod 提供*序号和唯一性保证*。 + + + + + +和 {{< glossary_tooltip term_id="Deployment" >}} 相同的是,StatefulSet 管理了基于相同容器定义的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个固定的 ID。这些 Pod 是基于相同的声明来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。 + + + +StatefulSet 和其他控制器使用相同的工作模式。你在 StatefulSet *对象* 中定义你期望的状态,然后 StatefulSet 的 *控制器* 就会通过各种更新来达到那种你想要的状态。 + diff --git a/content/zh/docs/reference/glossary/storage-class.md b/content/zh/docs/reference/glossary/storage-class.md new file mode 100644 index 0000000000000..52886478eb038 --- /dev/null +++ b/content/zh/docs/reference/glossary/storage-class.md @@ -0,0 +1,40 @@ + + +--- +title: 存储类别 +id: storageclass +date: 2018-04-12 +full_link: /docs/concepts/storage/storage-classes +short_description: > + StorageClass 是管理员用来描述不同的可用存储类型的一种方法。 + +aka: +tags: +- core-object +- storage +--- + + StorageClass 是管理员用来描述不同的可用存储类型的一种方法。 + + + + +StorageClass 可以映射到服务质量等级(QoS)、备份策略、或者管理员随机定义的策略。每个 StorageClass 对象包含的域有 `provisioner`、 `parameters` 和 `reclaimPolicy`,属于该存储类别的 {{< glossary_tooltip text="永久卷" term_id="persistent-volume" >}} 需要动态分配时就要用到这些域参数。通过 StorageClass 对象的名称,用户可以请求他们需要的特定存储类别。 + diff --git a/content/zh/docs/reference/glossary/sysctl.md b/content/zh/docs/reference/glossary/sysctl.md new file mode 100644 index 0000000000000..46a6dd98f32e9 --- /dev/null +++ b/content/zh/docs/reference/glossary/sysctl.md @@ -0,0 +1,51 @@ +--- +title: sysctl +id: sysctl +date: 2019-02-12 +full_link: /docs/tasks/administer-cluster/sysctl-cluster/ +short_description: > + 用于获取和设置 Unix 内核参数的接口 + +aka: +tags: +- 工具 +--- + + + + + + `sysctl` 是一个半标准化的接口,用于读取或更改正在运行的 Unix 内核的属性。 + + + + + +在类 Unix 系统上, `sysctl` 既是管理员用于查看和修改这些设置的工具的名称,也是该工具所调用的系统调用的名称。 + + + +{{< glossary_tooltip text="容器" term_id="container" >}} 运行时和网络插件可能对 `sysctl` 的取值有一定的要求。 diff --git a/content/zh/docs/reference/glossary/uid.md b/content/zh/docs/reference/glossary/uid.md new file mode 100755 index 0000000000000..4da74f8fadd34 --- /dev/null +++ b/content/zh/docs/reference/glossary/uid.md @@ -0,0 +1,42 @@ +--- +title: UID +id: uid +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/names +short_description: > + 由 Kubernetes 系统生成、用来唯一标识对象的字符串。 + +aka: +tags: +- fundamental +--- + + + + + +由 Kubernetes 系统生成、用来唯一标识对象的字符串。 + + + + + +在 Kubernetes 集群的整个生命周期中,每个被创建的对象都有不同的 UID。UID 用来区分相似实体的历史事件。 + diff --git a/content/zh/docs/reference/glossary/upstream.md b/content/zh/docs/reference/glossary/upstream.md new file mode 100644 index 0000000000000..7f2c7ded3e5f7 --- /dev/null +++ b/content/zh/docs/reference/glossary/upstream.md @@ -0,0 +1,27 @@ +--- +title: Upstream (disambiguation) +id: upstream +date: 2018-04-12 +full_link: +short_description: > + May refer to: core Kubernetes or the source repo from which a repo was forked. + +aka: +tags: +- community +--- + + + + +可以参考:核心 Kubernetes 仓库或作为当前仓库派生来源的来源仓库。 + + + +* 在 **Kubernetes社区**:对话中通常使用 *upstream* 来表示核心 Kubernetes 代码库,也就是更广泛的 kubernetes 生态系统、其他代码或第三方工具所依赖的仓库。 例如,[社区成员](#term-member)可能会建议将某个功能特性贡献到 upstream,使其位于核心代码库中,而不是维护于插件或第三方工具中。 +* 在 **GitHub** 或 **git** 中:约定是将源仓库称为 *upstream*,而派生的仓库则被视为 *downstream*。 diff --git a/content/zh/docs/reference/glossary/volume-plugin.md b/content/zh/docs/reference/glossary/volume-plugin.md new file mode 100755 index 0000000000000..ca4318d4ad205 --- /dev/null +++ b/content/zh/docs/reference/glossary/volume-plugin.md @@ -0,0 +1,44 @@ +--- +title: 卷(Volume)插件 +id: volumeplugin +date: 2018-04-12 +full_link: +short_description: > + 卷(Volume)插件可以让 Pod 集成存储。 + +aka: +tags: +- core-object +- storage +--- + + + + + +卷插件可以让 {{< glossary_tooltip text="Pod" term_id="pod" >}} 集成存储。 + + + + + +卷插件让您能给 {{< glossary_tooltip text="Pod" term_id="pod" >}} 附加和挂载存储卷。卷插件既可以是 _in tree_ 也可以是 _out of tree_ 。_in tree_ 插件是 Kubernetes 代码库的一部分,并遵循其发布周期。而 _Out of tree_ 插件则是独立开发的。 + diff --git a/content/zh/docs/reference/glossary/volume.md b/content/zh/docs/reference/glossary/volume.md new file mode 100755 index 0000000000000..279626861d4e7 --- /dev/null +++ b/content/zh/docs/reference/glossary/volume.md @@ -0,0 +1,43 @@ +--- +title: 卷 +id: volume +date: 2018-04-12 +full_link: /docs/concepts/storage/volumes/ +short_description: > + 包含可被 Pod 中容器访问的数据的目录。 + +aka: +tags: +- core-object +- fundamental +--- + + + + + +包含可被 {{< glossary_tooltip text="pod" term_id="pod" >}} 中容器访问的数据的目录。 + + + + +每个 Kubernetes 卷在所处的{{< glossary_tooltip text="pod" term_id="pod" >}} 存在期间保持存在状态。 +因此,卷的生命期会超出 {{< glossary_tooltip text="pod" term_id="pod" >}} 中运行的{{< glossary_tooltip text="容器" term_id="container" >}}, +并且保证{{< glossary_tooltip text="容器" term_id="container" >}}重启之后仍保留数据。 + diff --git a/content/zh/docs/reference/glossary/wg.md b/content/zh/docs/reference/glossary/wg.md new file mode 100644 index 0000000000000..9a42e77ab00a4 --- /dev/null +++ b/content/zh/docs/reference/glossary/wg.md @@ -0,0 +1,45 @@ +--- +title: WG (工作组) +id: wg +date: 2018-04-12 +full_link: https://github.com/kubernetes/community/blob/master/sig-list.md#master-working-group-list +short_description: > + 工作组是为了方便讨论和(或)推进执行一些短周期、窄范围、或者从委员会和 SIG 分离出来的项目、以及跨 SIG 的活动。 + +aka: +tags: +- community +--- + + + + + +工作组是为了方便讨论和(或)推进执行一些短周期、窄范围、或者从委员会和 SIG 分离出来的项目、以及跨 SIG 的活动。 + + + + + +工作组可以将人们组织起来,一起完成一项分散的任务。它组建简单,完成任务即可解散。 + +更多信息请参考 [kubernetes/community](https://github.com/kubernetes/community) 代码库和当前的 [SIGs 和工作组](https://github.com/kubernetes/community/blob/master/sig-list.md) 列表。 diff --git a/content/zh/docs/reference/issues-security/_index.md b/content/zh/docs/reference/issues-security/_index.md index 382a4ed66da36..b4f4e0c193cfe 100644 --- a/content/zh/docs/reference/issues-security/_index.md +++ b/content/zh/docs/reference/issues-security/_index.md @@ -2,4 +2,12 @@ title: Kubernetes 问题和安全 weight: 10 toc-hide: true ---- \ No newline at end of file +--- + + diff --git a/content/zh/docs/reference/issues-security/issues.md b/content/zh/docs/reference/issues-security/issues.md new file mode 100644 index 0000000000000..7976be7684892 --- /dev/null +++ b/content/zh/docs/reference/issues-security/issues.md @@ -0,0 +1,16 @@ +--- +title: Kubernetes 问题追踪 +weight: 10 +--- + + + + +Kubernetes 代码的问题追踪基于 [GitHub Issues](https://github.com/kubernetes/kubernetes/issues/) 进行。 diff --git a/content/zh/docs/reference/issues-security/security.md b/content/zh/docs/reference/issues-security/security.md new file mode 100644 index 0000000000000..a0fe43786a61a --- /dev/null +++ b/content/zh/docs/reference/issues-security/security.md @@ -0,0 +1,129 @@ +--- +title: Kubernetes 安全和信息披露 +aliases: [/security/] +content_template: templates/concept +weight: 20 +--- + + + +{{% capture overview %}} + +本页面介绍 Kubernetes 安全和信息披露相关的内容。 +{{% /capture %}} + +{{% capture body %}} + +## 安全公告 + + +加入 [kubernets-announce](https://groups.google.com/forum/#!forum/kubernetes-announce) 组,以获取关于安全性和主要 API 公告的电子邮件。 + + +## 报告一个漏洞 + + +我们非常感谢向 Kubernetes 开源社区报告漏洞的安全研究人员和用户。 +所有的报告都由社区志愿者进行彻底调查。 + + +如需报告,请连同安全细节以及预期的[所有 Kubernetes bug 报告](https://git.k8s.io/kubernetes/.github/ISSUE_TEMPLATE/bug-report.md)详细信息电邮到[security@kubernetes.io](mailto:security@kubernetes.io) 列表。 + + +您可以使用[产品安全团队成员](https://git.k8s.io/sig-release/security-release-process-documentation/security-release-process.md#product-security-team-pst)的 GPG 密钥加密您的电子邮件到此列表。 +使用 GPG 加密不需要公开。 + + +### 我应该在什么时候报告漏洞? + + +- 您认为在 Kubernetes 中发现了一个潜在的安全漏洞 +- 您不确定漏洞如何影响 Kubernetes +- 您认为您在 Kubernetes 依赖的另一个项目中发现了一个漏洞(例如 docker、rkt、etcd) + + +### 我什么时候不应该报告漏洞? + + +- 您需要帮助调整 Kubernetes 组件的安全性 +- 您需要帮助应用与安全相关的更新 +- 您的问题与安全无关 + + +## 安全漏洞响应 + + +每个报告在 3 个工作日内由产品安全团队成员确认和分析。这将启动[安全发布过程](https://git.k8s.io/sig-release/security-release-process-documentation/security-release-process.md#disclosures)。 + + +与产品安全团队共享的任何漏洞信息都保留在 Kubernetes 项目中,除非有必要修复该问题,否则不会传播到其他项目。 + + +随着安全问题从分类、识别修复、发布计划等方面的进展,我们将不断更新报告。 + + +## 公开披露时间 + + +公开披露日期由 Kubernetes 产品安全团队和 bug 提交者协商。我们倾向于在用户缓解措施可用时尽快完全披露该 bug。 + + +当 bug 或其修复还没有被完全理解,解决方案没有经过良好的测试,或者为了处理供应商协调问题时,延迟披露是合理的。 + + +信息披露的时间范围从即时(尤其是已经公开的)到几周。作为一个基本的约定,我们希望报告日期到披露日期的间隔是 7 天。在设置披露日期时,Kubernetes 产品安全团队拥有最终决定权。 +{{% /capture %}} diff --git a/content/zh/docs/reference/kubectl/_index.md b/content/zh/docs/reference/kubectl/_index.md index 7b6c2d720b12a..fb61e32478d09 100755 --- a/content/zh/docs/reference/kubectl/_index.md +++ b/content/zh/docs/reference/kubectl/_index.md @@ -1,5 +1,11 @@ --- -title: "kubectl CLI" +title: "kubectl 命令行界面" weight: 60 --- + diff --git a/content/zh/docs/reference/kubectl/cheatsheet.md b/content/zh/docs/reference/kubectl/cheatsheet.md new file mode 100644 index 0000000000000..ab949d4b5ec28 --- /dev/null +++ b/content/zh/docs/reference/kubectl/cheatsheet.md @@ -0,0 +1,663 @@ +--- +title: kubectl Cheat Sheet +reviewers: +- bgrant0607 +- erictune +- krousey +- clove +content_template: templates/concept +--- + +{{% capture overview %}} + + +也可以看下:[Kubectl 概述](/docs/reference/kubectl/overview/) 和 [JsonPath 指南](/docs/reference/kubectl/jsonpath)。 + + +本页面是 `kubectl` 命令的概述。 + +{{% /capture %}} + +{{% capture body %}} + +# kubectl - Cheat Sheet + + +## Kubectl 自动补全 + +### BASH + + +```bash +source <(kubectl completion bash) # 在 bash 中设置当前 shell 的自动补全,要先安装 bash-completion 包。 +echo "source <(kubectl completion bash)" >> ~/.bashrc # 在您的 bash shell 中永久的添加自动补全 +``` + +### ZSH + + +```bash +source <(kubectl completion zsh) # 在 zsh 中设置当前 shell 的自动补全 +echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # 在您的 zsh shell 中永久的添加自动补全 +``` + + +## Kubectl 上下文和配置 + +设置 `kubectl` 与哪个 Kubernetes 集群进行通信并修改配置信息。查看 [使用 kubeconfig 跨集群授权访问 +](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) 文档获取详情配置文件信息。 + + +```bash +kubectl config view # 显示合并的 kubeconfig 配置。 + +# 同时使用多个 kubeconfig 文件并查看合并的配置 +KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 kubectl config view + +# 获取 e2e 用户的密码 +kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}' + +kubectl config current-context # 展示当前所处的上下文 +kubectl config use-context my-cluster-name # 设置默认的上下文为 my-cluster-name + +# 添加新的集群配置到 kubeconf 中,使用 basic auth 进行鉴权 +kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword + +# 使用特定的用户名和命名空间设置上下文。 +kubectl config set-context gce --user=cluster-admin --namespace=foo \ + && kubectl config use-context gce +``` + + +## 创建对象 + +Kubernetes 配置可以用 json 或 yaml 定义。可以使用的文件扩展名有 `.yaml`, +`.yml` 和 `.json` 。 + + +```bash +kubectl create -f ./my-manifest.yaml # 创建资源 +kubectl create -f ./my1.yaml -f ./my2.yaml # 使用多个文件创建 +kubectl create -f ./dir # 从目录下的全部配置文件创建资源 +kubectl create -f https://git.io/vPieo # 从 url 中创建资源 +kubectl run nginx --image=nginx # 启动单实例 nginx +kubectl explain pods,svc # 获取 pod,svc 配置的文档说明 + +# 从标准输入中的多个 YAML 对象中创建 +cat < +## 获取和查找资源 + + +```bash +# 使用 get 命令获取基本输出 +kubectl get services # 列出当前命名空间下的所有 services +kubectl get pods --all-namespaces # 列出所有命名空间下的全部的 pods +kubectl get pods -o wide # 列出当前命名空间下的全部 pods,有更多的详细信息 +kubectl get deployment my-dep # 列出某个特定的 deployment +kubectl get pods --include-uninitialized # 列出当前命名空间下的全部 pods,包含未初始化的 + +# 使用 describe 命令获取详细输出 +kubectl describe nodes my-node +kubectl describe pods my-pod + +kubectl get services --sort-by=.metadata.name # 列出当前命名空间下所有 services,按照名称排序 + +# 列出 pods 按照重启次数进行排序 +kubectl get pods --sort-by='.status.containerStatuses[0].restartCount' + +# 获取包含 app=cassandra 标签全部 pods 的 version 标签 +kubectl get pods --selector=app=cassandra rc -o \ + jsonpath='{.items[*].metadata.labels.version}' + +# 获取当前命名空间中正在运行的 pods +kubectl get pods --field-selector=status.phase=Running + +# 获取全部 node 的 ExternalIP 地址 +kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}' + +# 列出属于某个特定 RC 的 pods 的名称 +# "jq" 命令对于 jsonpath 过于复杂的转换非常有用,可以在 https://stedolan.github.io/jq/ 找到它。 +sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?} +echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name}) + +# 检查哪些节点处于 ready +JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ + && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True" + +# 列出被一个 pod 使用的全部 secret +kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq + +# 列出 events,按照创建时间排序 +kubectl get events --sort-by=.metadata.creationTimestamp +``` + + +## 更新资源 + +从版本 1.11 开始,`rolling-update` 已被弃用(参见[CHANGELOG-1.11.md](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md)),请使用 `rollout` 代替。 + + +```bash +kubectl set image deployment/frontend www=image:v2 # 滚动更新 "frontend" deployment 的 "www" 容器镜像 +kubectl rollout undo deployment/frontend # 回滚到上次部署 +kubectl rollout status -w deployment/frontend # Watch "frontend" deployment 的滚动升级状态直到完成 + +# 从 1.11 版本开始弃用 +kubectl rolling-update frontend-v1 -f frontend-v2.json # (弃用) 滚动升级 frontend-v1 的 pods +kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # (弃用) 修改资源的名称并更新镜像 +kubectl rolling-update frontend --image=image:v2 # (弃用) 更新 frontend 的 pods 的镜像 +kubectl rolling-update frontend-v1 frontend-v2 --rollback # (弃用) 终止已经进行中的 rollout + +cat pod.json | kubectl replace -f - # 通过传入到标准输入的 JSON 来替换 pod + +# 强制进行替换,会删除然后再创建资源,会导致服务不可用。 +kubectl replace --force -f ./pod.json + +# 为多副本的 nginx 创建服务,使用 80 端口提供服务,连接到容器的 8000 端口。 +kubectl expose rc nginx --port=80 --target-port=8000 + +# 更新单容器 pod 的镜像标签到 v4 +kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f - + +kubectl label pods my-pod new-label=awesome # 添加标签 +kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # 添加注解 +kubectl autoscale deployment foo --min=2 --max=10 # 使 "foo" deployment 自动伸缩容 +``` + + +## 局部更新资源 + + +```bash +kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}' # 部分更新 node + +# 更新容器的镜像;spec.containers[*].name 是必须的因为它是一个合并 key。 +kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}' + +# 使用带位置数组的 json patch 更新容器的镜像 +kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]' + +# 使用带位置数组的 json patch 禁用 deployment 的 livenessProbe +kubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]' + +# 在带位置数组中添加元素 +kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]' +``` + + +## 编辑资源 +在编辑器中编辑任何 API 资源 + +```bash +kubectl edit svc/docker-registry # 编辑名为 docker-registry 的 service +KUBE_EDITOR="nano" kubectl edit svc/docker-registry # 使用其他编辑器 +``` + + +## 对资源进行伸缩 + +```bash +kubectl scale --replicas=3 rs/foo # 将名为 'foo' 的副本集伸缩到 3 副本 +kubectl scale --replicas=3 -f foo.yaml # 将在 "foo.yaml" 中的特定资源伸缩到 3 个副本 +kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # 如果名为 mysql 的 deployment 的副本当前是 2,那么将它伸缩到 3 +kubectl scale --replicas=5 rc/foo rc/bar rc/baz # 伸缩多个 replication controllers +``` + + +## 删除资源 + +```bash +kubectl delete -f ./pod.json # 删除在 pod.json 中指定的类型和名称的 pod +kubectl delete pod,service baz foo # 删除名称为 "baz" 和 "foo" 的 pod 和 service +kubectl delete pods,services -l name=myLabel # 删除包含 name=myLabel 标签的 pods 和 services +kubectl delete pods,services -l name=myLabel --include-uninitialized # 删除包含 label name=myLabel 标签的 pods 和 services,包括未初始化的 +kubectl -n my-ns delete po,svc --all # 删除在 my-ns 命名空间中全部的 pods 和 services ,包括未初始化的 +``` + + +## 与运行中的 Pods 进行交互 + +```bash +kubectl logs my-pod # 获取 pod 日志(标准输出) +kubectl logs my-pod --previous # 获取上个容器实例的 pod 日志(标准输出) +kubectl logs my-pod -c my-container # 获取 pod 的容器日志 (标准输出, 多容器的场景) +kubectl logs my-pod -c my-container --previous # 获取 pod 的上个容器实例日志 (标准输出, 多容器的场景) +kubectl logs -f my-pod # 流式输出 pod 的日志 (标准输出) +kubectl logs -f my-pod -c my-container # 流式输出 pod 容器的日志 (标准输出, 多容器的场景) +kubectl run -i --tty busybox --image=busybox -- sh # 以交互式 shell 运行 Pod +kubectl attach my-pod -i # 进入到一个运行中的容器中 +kubectl port-forward my-pod 5000:6000 # 在本地计算机上侦听端口 5000 并转发到 my-pod 上的端口 6000 +kubectl exec my-pod -- ls / # 在已有的 pod 中运行命令(单容器的场景) +kubectl exec my-pod -c my-container -- ls / # 在已有的 pod 中运行命令(多容器的场景) +kubectl top pod POD_NAME --containers # 显示给定 pod 和容器的监控数据 +``` + + +## 与节点和集群进行交互 + +```bash +kubectl cordon my-node # 设置 my-node 节点为不可调度 +kubectl drain my-node # 对 my-node 节点进行驱逐操作,为节点维护做准备 +kubectl uncordon my-node # 设置 my-node 节点为可以调度 +kubectl top node my-node # 显示指定节点的监控数据 +kubectl cluster-info # 限制 master 和 services 的地址 +kubectl cluster-info dump # 将当前集群状态输出到标准输出 +kubectl cluster-info dump --output-directory=/path/to/cluster-state # 将当前集群状态输出到 /path/to/cluster-state + +# 如果已存在具有该键和效果的污点,则其值将按指定替换 +kubectl taint nodes foo dedicated=special-user:NoSchedule +``` + + +### 资源类型 + +列出全部支持的资源类型和它们的简称, [API group](/docs/concepts/overview/kubernetes-api/#api-groups), 无论它们是否是 [namespaced](/docs/concepts/overview/working-with-objects/namespaces), [Kind](/docs/concepts/overview/working-with-objects/kubernetes-objects): + +```bash +kubectl api-resources +``` + +用于探索 API 资源的其他操作: + +```bash +kubectl api-resources --namespaced=true # 所有在命名空间中的资源 +kubectl api-resources --namespaced=false # 所有不在命名空间中的资源 +kubectl api-resources -o name # 输出简单的所有资源(只是资源名称) +kubectl api-resources -o wide # 具有扩展(又称 "wide")输出的所有资源 +kubectl api-resources --verbs=list,get # 支持"list"和"get"请求动词的所有资源 +kubectl api-resources --api-group=extensions # "extensions" API组中的所有资源 +``` + + +### 格式化输出 + +要以特定格式将详细信息输出到终端窗口,可以将 `-o` 或 `--output` 参数添加到支持的 `kubectl` 命令. + +输出格式 | 描述 +--------------| ----------- +`-o=custom-columns=` | 使用逗号分隔的自定义列列表打印表格 +`-o=custom-columns-file=` | 使用 `` 文件中的自定义列模板打印表格 +`-o=json` | 输出 JSON 格式的 API 对象 +`-o=jsonpath=