最大的坑是 deprecated apiVersion
Kubernetes 的 apiVersion 是会过期的
以 1.16来说,DaemonSet, Deployment, StatefulSet, ReplicaSet 全部统一使用 apps/v1
NetworkPolicy 使用 networking.k8s.io/v1
PodSecurityPolicy 使用 networking.k8s.io/v1
所以,在 1.16 中使用 apps/v1beta2, extensions/v1beta1 等废弃API都会出错
拥抱变化
检查受影响资源
1
2
3
4
5
6
7
8
9
10
11
12
kubectl get NetworkPolicy,PodSecurityPolicy,DaemonSet,Deployment,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"extensions/v1beta1"'
kubectl get DaemonSet,Deployment,StatefulSet,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"apps/v1beta'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="extensions"' | grep 'version="v1beta1"' | grep -v ingresses | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="apps"' | grep 'version="v1beta' | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
recreate
是的,你没有听错,只能删除后重建。
我的建议是,在业务低峰期,建同label deploy 覆盖旧的resource,旧的resource缩容至0,并加上deprecated:true的label观察一段时间后,再彻底删除.
后记
apiVersion 变动的频繁,在某种程度上也可以证明 Kubernetes 在容器调度方面的霸权——毕竟,如果你跟女朋友分手了,也不会想给她买新衣服,对吧?

参考链接
The Biggest Pitfall is Deprecated apiVersion
Kubernetes’s apiVersion can expire.
For 1.16, DaemonSet, Deployment, StatefulSet, ReplicaSet all uniformly use apps/v1
NetworkPolicy uses networking.k8s.io/v1
PodSecurityPolicy uses networking.k8s.io/v1
So, using deprecated APIs like apps/v1beta2, extensions/v1beta1 in 1.16 will error.
Embrace Change
Check Affected Resources
1
2
3
4
5
6
7
8
9
10
11
12
kubectl get NetworkPolicy,PodSecurityPolicy,DaemonSet,Deployment,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"extensions/v1beta1"'
kubectl get DaemonSet,Deployment,StatefulSet,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"apps/v1beta'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="extensions"' | grep 'version="v1beta1"' | grep -v ingresses | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="apps"' | grep 'version="v1beta' | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
recreate
Yes, you heard right, you can only delete and recreate.
My suggestion is, during business low peak, create a deploy with the same label to cover the old resource, scale the old resource to 0, and add a deprecated:true label, observe for a period, then completely delete.
Postscript
The frequency of apiVersion changes, to some extent, can also prove Kubernetes’s hegemony in container scheduling—after all, if you break up with your girlfriend, you wouldn’t want to buy her new clothes, right?

Reference Links
最大の落とし穴は非推奨のapiVersionです
KubernetesのapiVersionは期限切れになる可能性があります
1.16の場合、DaemonSet、Deployment、StatefulSet、ReplicaSetはすべてapps/v1を統一して使用します
NetworkPolicyはnetworking.k8s.io/v1を使用します
PodSecurityPolicyはnetworking.k8s.io/v1を使用します
したがって、1.16でapps/v1beta2、extensions/v1beta1などの非推奨APIを使用するとエラーになります。
変化を受け入れる
影響を受けるリソースを確認
1
2
3
4
5
6
7
8
9
10
11
12
kubectl get NetworkPolicy,PodSecurityPolicy,DaemonSet,Deployment,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"extensions/v1beta1"'
kubectl get DaemonSet,Deployment,StatefulSet,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"apps/v1beta'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="extensions"' | grep 'version="v1beta1"' | grep -v ingresses | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="apps"' | grep 'version="v1beta' | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
recreate
はい、聞き間違いではありません。削除して再作成するしかありません。
私の提案は、ビジネスの低ピーク時に、同じラベルでdeployを作成して古いresourceをカバーし、古いresourceを0にスケールし、deprecated:trueのlabelを追加してしばらく観察した後、完全に削除することです。
後記
apiVersionの変更の頻度は、ある程度、Kubernetesのコンテナスケジューリングにおける覇権を証明することもできます—結局のところ、ガールフレンドと別れた場合、新しい服を買いたくないでしょう、そうでしょう?

参考リンク
Самая большая ловушка — устаревший apiVersion
apiVersion в Kubernetes может истечь.
Для 1.16 DaemonSet, Deployment, StatefulSet, ReplicaSet все единообразно используют apps/v1
NetworkPolicy использует networking.k8s.io/v1
PodSecurityPolicy использует networking.k8s.io/v1
Поэтому использование устаревших API, таких как apps/v1beta2, extensions/v1beta1 в 1.16, вызовет ошибку.
Принять изменения
Проверить затронутые ресурсы
1
2
3
4
5
6
7
8
9
10
11
12
kubectl get NetworkPolicy,PodSecurityPolicy,DaemonSet,Deployment,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"extensions/v1beta1"'
kubectl get DaemonSet,Deployment,StatefulSet,ReplicaSet \
--all-namespaces \
-o 'jsonpath={range .items[*]}{.metadata.annotations.kubectl\.kubernetes\.io/last-applied-configuration}{"\n"}{end}' | grep '"apiVersion":"apps/v1beta'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="extensions"' | grep 'version="v1beta1"' | grep -v ingresses | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
kubectl get --raw="/metrics" | grep apiserver_request_count | grep 'group="apps"' | grep 'version="v1beta' | grep -v 'client="hyperkube' | grep -v 'client="kubectl' | grep -v 'client="dashboard'
recreate
Да, вы не ослышались, можно только удалить и пересоздать.
Мое предложение: в период низкой нагрузки бизнеса создать deploy с тем же label, чтобы покрыть старый resource, масштабировать старый resource до 0 и добавить label deprecated:true, понаблюдать некоторое время, затем полностью удалить.
Послесловие
Частота изменений apiVersion в некоторой степени также может доказать гегемонию Kubernetes в планировании контейнеров—в конце концов, если вы расстаетесь с подругой, вы не захотите покупать ей новую одежду, верно?

Ссылки
💬 讨论 / Discussion
对这篇文章有想法?欢迎在 GitHub 上发起讨论。
Have thoughts on this post? Start a discussion on GitHub.