Qrunch から引っ越し
kubectl drain した時、テストで作った ownerReference の無い Pod がいたために怒られた。
(これらの Pod は --force オプションで削除させることができる)
ふと kube-proxy のことを思い出し、気になって調べた。
GKE だと kube-proxy は /etc/kubernetes/manifests から起動されていて ownerReference は無いはずなのだが、どうやって drain を回避しているのだろうか。
ファイルの manifest から起動しているのでそもそも API server 経由で実際の Pod 削除はできないのだが、Pod の定義だけ (一時的に) 削除することはあり得るのでは?
pkg/kubectl/cmd/drain.go
を読むと分かる。
RunDrain()
deleteOrEvictPodsSimple()
getPodsForDeletion()
deleteOrEvictPods()
kubectl drain コマンドにはいくつかのフィルタ条件があり、それらが適用されて残った Pod が
deleteOrEvictPods()
に渡される。
各フィルタは getPodsForDeletion()
の中で適用される。
// getPodsForDeletion receives resource info for a node, and returns all the pods from the given node that we
// are planning on deleting. If there are any pods preventing us from deleting, we return that list in an error.
func (o *DrainOptions) getPodsForDeletion(nodeInfo *resource.Info) (pods []corev1.Pod, err error) {
labelSelector, err := labels.Parse(o.PodSelector)
if err != nil {
return pods, err
}
podList, err := o.client.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{
LabelSelector: labelSelector.String(),
FieldSelector: fields.SelectorFromSet(fields.Set{"spec.nodeName": nodeInfo.Name}).String()})
if err != nil {
return pods, err
}
ws := podStatuses{}
fs := podStatuses{}
for _, pod := range podList.Items {
podOk := true
for _, filt := range []podFilter{o.daemonsetFilter, mirrorPodFilter, o.localStorageFilter, o.unreplicatedFilter} {
filterOk, w, f := filt(pod)
podOk = podOk && filterOk
-l, --selector=''
は drain 対象の Node をフィルタするもので、Pod に作用するものではない。--pod-selector=''
で drain で処理する Pod をフィルタする。--pod-selector='key!=value'
をつける--ignore-daemonsets
は DaemonSet から作成された Pod を除外する。(daemonsetFilter)--delete-local-data
は emptyDir ボリュームを持つ Pod を除外する。(localStorageFilter)ownerRefernece の有無は unreplicatedFilter で判定されるが、kube-proxy が除外されるのは mirrorPodFilter だった。
func mirrorPodFilter(pod corev1.Pod) (bool, *warning, *fatal) {
if _, found := pod.ObjectMeta.Annotations[corev1.MirrorPodAnnotationKey]; found {
return false, nil, nil
}
return true, nil, nil
}
annotation の定義は pkg/apis/core/annotation_key_constants.go
を参照する。
// MirrorAnnotationKey represents the annotation key set by kubelets when creating mirror pods
MirrorPodAnnotationKey string = "kubernetes.io/config.mirror"
kubernetes.io/config.mirror
という annotation を持っているかどうかでフィルタされているようだ。
Mirror Pod って何だ?と思ってググると
Statis Pod が API server 側で見えるようになっているもの (見えるだけで API から制御できないもの) のことを指すらしい。
Static Pod は kubelet が API server ではなく ファイルや HTTP 経由で渡された manifest を元に 作成・起動した Pod のこと => Static Pods
調べてから見つけたが、詳しく説明している記事があった => Draining Kubernetes nodes
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント