Ansible剧本等到所有Pod都在运行

时间:2018-11-07 22:05:09

标签: kubernetes ansible

我有一个有趣的(工作中)剧本,它查看kubectl get pods -o json的输出,直到吊舱处于Running状态。现在,我想将其扩展到多个吊舱。核心问题是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]访问用于处理列表中一个对象的第一个项目,但是我不知道如何将其扩展到多个项目。我尝试了[*],但没有用。

3 个答案:

答案 0 :(得分:4)

我会尝试类似的方法(对我有用)

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"]的信息。

答案 1 :(得分:1)

kubectl wait命令

Kubernetes推出了kubectl wait版的v1.11

CHANGELOG-1.11:

  
      
  • kubectl wait是一项新命令,允许等待一个或多个   要删除的资源或达到特定条件的资源。它增加了一个   kubectl wait --for=[delete|condition=condition-name]资源/字符串   命令。
  •   

CHANGELOG-1.13:

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

CHANGELOG-1.14:

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

它不是要等待阶段,而是要等待条件。我认为,等待条件比等待阶段要更加自信。请参阅以下conditions

  
      
  • PodScheduled :已将Pod调度到一个节点;
  •   
  • 就绪:该Pod能够处理请求,应将其添加到所有匹配服务的负载平衡池中;
  •   
  • 已初始化:所有初始化容器已成功启动;
  •   
  • ContainersReady :容器中的所有容器均已准备就绪。
  •   

kubectl wait与Ansible一起使用

假设您正在使用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"
    ]    
}

答案 2 :(得分:1)

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"