kubernetes Ansible Playbook等待所有Pod运行

c9x0cxw0  于 2023-05-06  发布在  Kubernetes
关注(0)|答案(7)|浏览(171)

我有这个ansible(工作)剧本,它会查看kubectl get pods -o json的输出,直到pod处于Running状态。现在我想把它扩展到多个pod。核心问题是,kubectl查询的json结果是一个列表,我知道如何访问第一项,但不是所有项...

- name: wait for pods to come up
  shell: kubectl get pods -o json
  register: kubectl_get_pods
  until: kubectl_get_pods.stdout|from_json|json_query('items[0].status.phase') == "Running"
  retries: 20

json对象看起来像

[  { ...  "status": { "phase": "Running" } },
   { ...  "status": { "phase": "Running" } },
   ...
]

使用[0]访问第一个项目可以处理列表中的一个对象,但我不知道如何将其扩展到多个项目。我试过[*],但没有用。

sqserrrh

sqserrrh1#

kubectl wait命令

Kubernetes在v1.11版本中引入了kubectl wait
CHANGELOG-1.11:

  • kubectl wait是一个新命令,允许等待一个或多个资源被删除或达到特定条件。它添加了一个kubectl wait --for=[delete|condition=condition-name] resource/string命令。

CHANGELOG-1.13:

  • kubectl wait现在支持使用--for condition=available=false检查除true以外的条件值

CHANGELOG-1.14:

  • 扩展了kubectl wait以使用更多类型的选择器。
  • kubectl wait命令现在支持--all标志来选择指定资源类型的命名空间中的所有资源。

它不是要等待 * 阶段 *,而是等待 * 条件 *。我认为等待条件比等待阶段更有自信。参见以下 * 条件 *:

*PodScheduled:Pod已调度到节点;
*Ready:Pod能够服务请求,需要加入所有匹配的Service的负载均衡池;
*初始化:所有init容器已成功启动;
*ContainersReady:舱里的所有容器都准备好了

在Ansible中使用kubectl wait

假设您正在使用kubeadm + Ansible自动安装Kubernetes,并且需要等待安装完成:

- name: Wait for all control-plane pods become created
  shell: "kubectl get po --namespace=kube-system --selector tier=control-plane --output=jsonpath='{.items[*].metadata.name}'"
  register: control_plane_pods_created
  until: item in control_plane_pods_created.stdout
  retries: 10
  delay: 30
  with_items:
    - etcd
    - kube-apiserver
    - kube-controller-manager
    - kube-scheduler

- name: Wait for control-plane pods become ready
  shell: "kubectl wait --namespace=kube-system --for=condition=Ready pods --selector tier=control-plane --timeout=600s"
  register: control_plane_pods_ready

- debug: var=control_plane_pods_ready.stdout_lines

结果示例:

TASK [Wait for all control-plane pods become created] ******************************
FAILED - RETRYING: Wait all control-plane pods become created (10 retries left).
FAILED - RETRYING: Wait all control-plane pods become created (9 retries left).
FAILED - RETRYING: Wait all control-plane pods become created (8 retries left).
changed: [localhost -> localhost] => (item=etcd)
changed: [localhost -> localhost] => (item=kube-apiserver)
changed: [localhost -> localhost] => (item=kube-controller-manager)
changed: [localhost -> localhost] => (item=kube-scheduler)

TASK [Wait for control-plane pods become ready] ********************************
changed: [localhost -> localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "control_plane_pods_ready.stdout_lines": [
        "pod/etcd-localhost.localdomain condition met", 
        "pod/kube-apiserver-localhost.localdomain condition met", 
        "pod/kube-controller-manager-localhost.localdomain condition met", 
        "pod/kube-scheduler-localhost.localdomain condition met"
    ]    
}
sr4lhrrt

sr4lhrrt2#

我会尝试这样的方法(对我有效):

tasks:
- name: wait for pods to come up
  shell: kubectl get pods -o json
  register: kubectl_get_pods
  until: kubectl_get_pods.stdout|from_json|json_query('items[*].status.phase')|unique == ["Running"]

您基本上是获取所有pod的所有状态并将它们组合到一个唯一的列表中,然后直到该列表为["Running"]时才完成。例如,如果您的所有pod都没有运行,您将获得类似["Running", "Starting"]的内容。

v6ylcynt

v6ylcynt3#

Ansible的community.kubernetes.k8s插件有一个内置的等待功能!
然而,这样做的问题是,不同的资源具有不同的wait_condition类型。如果你使用的是deployment,那么如下所示,只要你设置了正确的超时界限,type: Complete就可以正常工作,但是如果你在yaml中有不同的资源类型,比如serviceaccounts,它很可能会挂起。

- name: Deploy the stack
  community.kubernetes.k8s:
    state: present
    src: "{{ dir }}my.yaml"
    wait: yes
    wait_sleep: 10
    wait_timeout: 600
    wait_condition:
      type: Complete
      status: "True"
qojgxg4l

qojgxg4l4#

您可以从kubernetes.core collection使用kubernetes.core.k8s_info
例如,等待cert-manager在cert-manager命名空间中启动:

- name: Wait until cert-manager is up
  kubernetes.core.k8s_info:
    kubeconfig: "{{ kubeconfig }}"
    api_version: v1
    kind: Pod
    namespace: cert-manager
  register: pod_list
  until: pod_list|json_query('resources[*].status.phase')|unique == ["Running"]
neskvpey

neskvpey5#

Kubernetes版本v1.23.0(changelog)增加了kubectl wait在任意JSON路径上等待的功能。
因此,现在似乎也可以使用kubectl wait来等待状态阶段。
等待pod“busybox1”包含状态阶段为“Running”:

kubectl wait --for=jsonpath='{.status.phase}'=Running pod/busybox1

您可以在ansible playbook任务中使用此命令:

- name: Wait for the pods to come up with status 'Running'
  shell: "kubectl wait -n kube-system --for=jsonpath='{.status.phase}'=Running pods --selector tier=control-plane --timeout=120s"
  register: control_plane_pods_running

- debug: var=control_plane_pods_running.stdout_lines
jchrr9hc

jchrr9hc6#

一行shell命令可以执行以下操作:

kubectl wait pod --all -n ${the_namespace} --timeout=3m \
--for=condition=ready --field-selector=status.phase!=Succeeded

它将等待最多3分钟,以使所有pod都在命名空间中运行。字段选择器用于忽略Succeeded(大写“S”很重要)的已完成pod。

fivyi3re

fivyi3re7#

最后,我选择了https://stackoverflow.com/users/2989261/rico的答案,因为它看起来是最可靠的(kubectl wait --for=confition=ready在我的kubectl版本1.23.5中不可靠),并为我的所有pod添加了一个选择器(这是一个过滤已完成作业的好方法),如下所示:

tasks:
- name: wait for pods from group app-xx to come up
  shell: kubectl get pods --selector=app-group=app-xx -o json
  register: kubectl_get_pods
  until: kubectl_get_pods.stdout|from_json|json_query('items[*].status.phase')|unique == ["Running"]
  retries: 12
  delay: 5

相关问题