K8s: 最佳实践经验之谈
2 )关于“Naked”Pods 与 ReplicaSet,Deployment 和 Jobs。当 Kubernetes 启动容器时,它提供指向启动容器时正在运行的所有服务的环境变量。Deployment 描述了对象的期望状态,并且如果对该规范的更改被成功应用。在创建相应的后端工作负载(Deployment 或 ReplicaSet)例如,如果存在名为 foo 的服务,则所有容器将在其初始环境中获
·
最佳实践
1 )普通配置
- 定义配置时,请指定最新的稳定 API 版本
- 在推送到集群之前,配置文件应存储在版本控制中
- 这允许您在必要时快速回滚配置更改
- 它还有助于集群重新创建和恢复
- 使用 YAML 而不是 JSON 编写配置文件
- 虽然这些格式几乎可以在所有场景中互换使用
- 但 YAML往往更加用户友好
- 只要有意义,就将相关对象分组到一个文件中 (推荐)
- 一个文件通常比几个文件更容易管理
- 另请注意,可以在目录上调用许多kubectl命令 (相比于上面,不推荐)
- 例如,你可以在配置文件的目录中调用
kubectl apply
- 例如,你可以在配置文件的目录中调用
2 )关于“Naked”Pods 与 ReplicaSet,Deployment 和 Jobs
- 如果可能,不要使用独立的 Pods
- 即,未绑定到 ReplicaSet 或 Deployment 的 Pod
- 如果节点发生故障,将不会重新调度独立的 Pods
- Deployment 会创建一个 ReplicaSet 以确保所需数量的 Pod 始终可用
- 并指定替换 Pod 的策略(例如 RollingUpdate)
- 除了一些显式的restartPolicy: Never 场景之外
- 几乎总是优先考虑直接创建 Pod
- Job 也可能是合适的
3 )服务
-
在创建相应的后端工作负载(Deployment 或 ReplicaSet)
-
以及在需要访问它的任何工作负载之前创建服务
-
当 Kubernetes 启动容器时,它提供指向启动容器时正在运行的所有服务的环境变量
-
例如,如果存在名为 foo 的服务,则所有容器将在其初始环境中获得以下变量
FOO_SERVICE_HOST=<the host the Service is running on> FOO_SERVICE_PORT=<the port the Service is running on>
-
这确实意味着在顺序上的要求
- 必须在 Pod 本身被创建之前创建 Pod 想要访问的任何 Service
- 否则将环境变量不会生效,而 DNS 没有此限制
-
一个可选(尽管强烈推荐)的集群插件 是 DNS 服务器
- DNS 服务器为新的 Services 监视Kubernetes API,并为每个创建一组 DNS 记录
- 如果在整个集群中启用了 DNS,则所有 Pods 应该能够自动对 Services 进行名称解析
- Service 有虚拟ip, 这些ip会被注册在域名服务器DNS上
- 所有worknode上的pod都能找到集群内的所有Service
-
除非绝对必要,否则不要为 Pod 指定 hostPort
- 就是 worknode 节点挂掉,Pod就没法调度了
- 将 Pod 绑定到hostPort时,它会限制 Pod 可以调度的位置数
- 因为每个
<hostIP, hostPort, protocol>
组合必须是唯一的 - 如果没有明确指定 hostIP 和 protocol 时,
- K8s 将使用 0.0.0.0 作为默认 hostIP 和 TCP 作为默认 protocol
- 如果只需要访问端口以进行调试,则可以使用 apiserver proxy或 kubectl port-forward
-
如果明确需要在节点上公开 Pod 的端口
- 请在使用 hostPort 之前考虑使用 NodePort 服务
-
避免使用 hostNetwork
- 原因与 hostPort 相同。
-
当不需要 kube-proxy 负载均衡时
- 使用 无头服务(ClusterIP 被设置为 None)
- 以便于服务发现
4 )使用标签
-
定义并使用标签来识别应用程序 或 Deployment 的 语义属性
- 例如
{ app: myapp, tier: frontend, phase: test, deployment: v3 }
- 这种属于应用分组,好处是互不影响
- 你可以使用这些标签为其他资源选择合适的 Pod
- 例如,一个选择所有 tier: frontend Pod 的服务
- 或者 app: myapp 的所有 phase: test 组件
- 例如
-
通过从选择器中省略特定发行版的标签
- 可以使服务跨越多个 Deployment
- Deployment 可以在不停机的情况下轻松更新正在运行的服务
-
Deployment 描述了对象的期望状态,并且如果对该规范的更改被成功应用
- 则 Deployment 控制器以受控速率将实际状态改变为期望状态
5 )容器镜像
- imagePullPolicy和镜像标签会影响kubelet何时尝试拉取指定的镜像
imagePullPolicy: IfNotPresent
:仅当镜像在本地不存在时才被拉取imagePullPolicy: Always
:每次启动 Pod 的时候都会拉取镜像imagePullPolicy
省略时,镜像标签为 :latest 或不存在,使用 Always 值imagePullPolicy
省略时,指定镜像标签并且不是 :latest,使用 IfNotPresent 值imagePullPolicy: Never
:假设镜像已经存在本地,不会尝试拉取镜像
- 说明
- 在生产中部署容器时应避免使用 :latest 标记
- 因为这样更难跟踪正在运行的镜像版本,并且更难以正确回滚
- 底层镜像驱动程序的缓存语义能够使即便 imagePullPolicy: Always 的配置也很高效
- 例如,对于 Docker,如果镜像已经存在,则拉取尝试很快,因为镜像层都被缓存并且不需要下载
6 )使用 kubectl
- 选择使用 $
kubectl apply -f
更灵活 - 使用标签选择器进行 get 和 delete 操作,而不是特定的对象名称
7 )kubectl apply -f 和 kubectl create -f 区别
-
行为差异
- kubectl create -f
- 这个命令用于根据提供的配置文件(通常是 YAML 或 JSON 格式)创建 Kubernetes 对象
- 如果对应的资源已经存在,它会返回错误
- 因此,在使用 create 命令之前,你需要确保资源对象不存在,或者先删除原有的资源对象
- kubectl apply -f
- 这个命令也是用于根据配置文件应用 Kubernetes 对象
- 但是,如果资源对象已经存在,apply 命令会尝试更新对应的字段值和配置,而不是报错
- 如果资源对象不存在,apply 命令会自动创建资源对象
- 因此,apply 命令提供了更大的灵活性,既可以用于创建新对象,也可以用于更新现有对象
- kubectl create -f
-
记录差异
- kubectl apply 命令通过将先前应用的配置写入资源的注释来维护配置记录
- 这有助于计算下一次调用时的差异,从而精确地知道需要应用哪些更改
- 这种机制使得 apply 命令在处理复杂的混合 IT 场景时特别有用
- 相比之下,kubectl create 命令不会维护这样的记录
- 它只是简单地根据提供的配置文件创建资源对象。
-
其他选项
- kubectl apply 还提供了许多可选的参数
- 如 --force、–validate 和 --record 等,这些参数可以使更新操作更加精确和可控
- 例如,–force 参数可以强制应用配置,即使某些字段可能会导致无效的资源定义
- kubectl create 命令通常没有这么多可选参数,它主要关注于根据配置文件创建资源对象
-
总的来说
- kubectl apply -f 和 kubectl create -f 在行为、记录和其他选项方面存在显著差异
- 选择使用哪个命令取决于你的具体需求,例如是否需要更新现有资源对象,是否需要维护配置记录等
- 在大多数情况下,kubectl apply 可能是一个更灵活和强大的选择
- 因为它既可以用于创建新对象,也可以用于更新现有对象
更多推荐
已为社区贡献32条内容
所有评论(0)