8.1 KiB
Kubernetes配置最佳实践
本文翻译自Kubernetes官方文档Configuration Best Practices。
本文档旨在汇总和强调用户指南、快速开始文档和示例中的最佳实践。该文档会很很活跃并持续更新中。如果你觉得很有用的最佳实践但是本文档中没有包含,欢迎给我们提Pull Request。
通用配置建议
- 定义配置文件的时候,指定最新的稳定API版本(目前是V1)。
- 在配置文件push到集群之前应该保存在版本控制系统中。这样当需要的时候能够快速回滚,必要的时候也可以快速的创建集群。
- 使用YAML格式而不是JSON格式的配置文件。在大多数场景下它们都可以作为数据交换格式,但是YAML格式比起JSON更易读和配置。
- 尽量将相关的对象放在同一个配置文件里。这样比分成多个文件更容易管理。参考guestbook-all-in-one.yaml文件中的配置(注意,尽管你可以在使用
kubectl
命令时指定配置文件目录,你也可以在配置文件目录下执行kubectl create
——查看下面的详细信息)。 - 为了简化和最小化配置,也为了防止错误发生,不要指定不必要的默认配置。例如,省略掉
ReplicationController
的selector和label,如果你希望它们跟podTemplate
中的label一样的话,因为那些配置默认是podTemplate
的label产生的。更多信息请查看 guestbook app 的yaml文件和 examples 。 - 将资源对象的描述放在一个annotation中可以更好的内省。
裸奔的Pods vs Replication Controllers和 Jobs
- 如果有其他方式替代“裸奔的pod”(如没有绑定到replication controller 上的pod),那么就使用其他选择。在node节点出现故障时,裸奔的pod不会被重新调度。Replication Controller总是会重新创建pod,除了明确指定了
restartPolicy: Never
的场景。Job 对象也适用。
Services
- 通常最好在创建相关的replication controllers之前先创建service(没有这个必要吧?)你也可以在创建Replication Controller的时候不指定replica数量(默认是1),创建service后,在通过Replication Controller来扩容。这样可以在扩容很多个replica之前先确认pod是正常的。
- 除非时分必要的情况下(如运行一个node daemon),不要使用
hostPort
(用来指定暴露在主机上的端口号)。当你给Pod绑定了一个hostPort
,该pod可被调度到的主机的受限了,因为端口冲突。如果是为了调试目的来通过端口访问的话,你可以使用 kubectl proxy and apiserver proxy 或者 kubectl port-forward。你可使用 Service 来对外暴露服务。如果你确实需要将pod的端口暴露到主机上,考虑使用 NodePort service。 - 跟
hostPort
一样的原因,避免使用hostNetwork
。 - 如果你不需要kube-proxy的负载均衡的话,可以考虑使用使用headless services。
使用Label
-
定义 labels 来指定应用或Deployment的 semantic attributes 。 For example, instead of attaching a label to a set of pods to explicitly represent some service (e.g.,
service: myservice
), or explicitly representing the replication controller managing the pods (e.g.,controller: mycontroller
), attach labels that identify semantic attributes, such as{ app: myapp, tier: frontend, phase: test, deployment: v3 }
. This will let you select the object groups appropriate to the context— e.g., a service for all “tier: frontend” pods, or all “test” phase components of app “myapp”. See the guestbook app for an example of this approach.A service can be made to span multiple deployments, such as is done across rolling updates, by simply omitting release-specific labels from its selector, rather than updating a service’s selector to match the replication controller’s selector fully.
-
为了滚动升级的方便,在Replication Controller的名字中包含版本信息,例如作为名字的后缀。设置一个
version
标签页是很有用的。滚动更新创建一个新的controller而不是修改现有的controller。因此,version含混不清的controller名字就可能带来问题。查看Rolling Update Replication Controller文档获取更多关于滚动升级命令的信息。注意 Deployment 对象不需要再管理 replication controller 的版本名。Deployment 中描述了对象的期望状态,如果对spec的更改被应用了话,Deployment controller 会以控制的速率来更改实际状态到期望状态。(Deployment目前是
extensions
API Group的一部分)。 -
利用label做调试。因为Kubernetes replication controller和service使用label来匹配pods,这允许你通过移除pod中的label的方式将其从一个controller或者service中移除,原来的controller会创建一个新的pod来取代移除的pod。这是一个很有用的方式,帮你在一个隔离的环境中调试之前的“活着的” pod。查看
kubectl label
命令。
容器镜像
-
默认容器镜像拉取策略 是
IfNotPresent
, 当本地已存在该镜像的时候 Kubelet 不会再从镜像仓库拉取。如果你希望总是从镜像仓库中拉取镜像的话,在yaml文件中指定镜像拉取策略为Always
(imagePullPolicy: Always
)或者指定镜像的tag为:latest
。如果你没有将镜像标签指定为
:latest
,例如指定为myimage:v1
,当该标签的镜像进行了更新,kubelet也不会拉取该镜像。你可以在每次镜像更新后都生成一个新的tag(例如myimage:v2
),在配置文件中明确指定该版本。注意: 在生产环境下部署容器应该尽量避免使用
:latest
标签,因为这样很难追溯到底运行的是哪个版本的容器和回滚。
Using kubectl
- 尽量使用
kubectl create -f <directory>
。kubeclt会自动查找该目录下的所有后缀名为.yaml
、.yml
和.json
文件并将它们传递给create
命令。 - 使用
kubectl delete
而不是stop
.Delete
是stop
的超集,stop
已经被弃用。 - 使用 kubectl bulk 操作(通过文件或者label)来get和delete。查看label selectors 和 using labels effectively。
- 使用
kubectl run
和expose
命令快速创建直有耽搁容器的Deployment。查看 quick start guide中的示例。