"Error: Could not get lock /var/lib/dpkg/lock-frontend - Trying to Install Kubernetes Components on AWS EC2 using Ansible"

I’m encountering an issue while running an Ansible playbook to set up a Kubernetes cluster. The playbook includes tasks to install Kubernetes components (kubelet , kubeadm , kubectl ) on multiple nodes. However, I’m facing the following error:

This error suggests that another process is currently holding the lock on /var/lib/dpkg/lock-frontend, preventing the installation process from proceeding. I suspect this might be due to another apt-get process running concurrently.

Here’s a summary of the playbook:

  • It sets up and configures the environment, including disabling swap, installing prerequisites, adding repositories, configuring modules, and installing Docker and Kubernetes components.
  • It initializes the Kubernetes master node and joins the worker nodes to the cluster.

Here is my playbook.yml where I am trying to install these packages
- name: Install kubeadm, kubectl, kubelet
ansible.builtin.apt:
pkg:
- kubelet
- kubeadm
- kubectl
state: present

However, during the installation of Kubernetes components (kubelet, kubeadm, kubectl) on the worker nodes, the error occurs.

I’ve tried checking for any ongoing apt-get processes on the affected nodes, but couldn’t find any. Is there any way to troubleshoot and resolve this issue?

Any insights or suggestions on how to resolve this problem would be greatly appreciated. Thank you!

You might also get this message if you were trying to interact with apt-get as a non-root user, so your playbook needs to up to operate this task as root.

Also: if you post parts of a playbook, to prevent the forum software from mangling the YAML, please

use code blocks
  to preserve 
  special characters (like ' and ")
     and indentation

I am running as root user, below is my complete playbook

---
- name: Initial setup and configuration
  hosts: all
  become: true
  gather_facts: false
  tasks:
    - name: Wait 300 seconds for port 22 
      ansible.builtin.wait_for:
        port=22 
        host="{{ (ansible_ssh_host|default(ansible_host))|default(inventory_hostname) }}" 
        search_regex=OpenSSH 
        delay=10 
        timeout=300
    - name: Set hostname
      ansible.builtin.hostname:
        name: "{{ inventory_hostname }}"

    - name: Add ip to /etc/hosts
      lineinfile:
        dest: /etc/hosts
        line: "{{ hostvars[item]['ansible_host'] }} {{ item }}"
      loop: "{{ groups['all'] }}"

    - name: Disable swap on each node
      ansible.builtin.shell: swapoff -a

    - name: Configure prerequesites
      ansible.builtin.shell:
        cmd: |
          cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
          overlay
          br_netfilter
          EOF

    - name: Install some prerequisites
      apt:
        name:
          - apt-transport-https
          - ca-certificates
          - lsb-release
          - curl
          - gnupg
          - gpg
        state: present

    - name: Create keyrings directory
      file: 
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'
        
    - name: Add docker gpg key
      shell: |
        sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
        sudo chmod a+r /etc/apt/keyrings/docker.asc        

    - name: Add docker repository
      shell: |
        echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    - name: Install docker prerequisites
      apt:
        name:
          - docker-ce
          - docker-ce-cli
          - containerd.io 
          - docker-buildx-plugin
          - docker-compose-plugin
        state: present
        update_cache: yes
      register: apt_status
      until: apt_status is success
      delay: 6
      retries: 10

    - name: Load overlay module
      community.general.modprobe:
        name: overlay
        state: present
        
    - name: add Kubernetes apt-key
      get_url:
        url: https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key
        dest: /etc/apt/keyrings/kubernetes-apt-keyring.asc
        mode: '0644'
        force: true

    - name: add Kubernetes' APT repository
      ansible.builtin.apt_repository:
        repo: "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /"
        state: present
        update_cache: yes

    - name: Load br_netfilter module
      community.general.modprobe:
        name: br_netfilter
        state: present

    - name: Sysctl params required by setup
      ansible.builtin.shell:
        cmd: |
          cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
          net.bridge.bridge-nf-call-iptables = 1
          net.bridge.bridge-nf-call-ip6tables = 1
          net.ipv4.ip_forward = 1
          EOF

    - name: Apply sysctl params without reboot
      ansible.builtin.shell: sysctl --system

    - name: Create containerd config file
      ansible.builtin.shell: mkdir -p /etc/containerd && touch /etc/containerd/config.toml

    - name: Configure systemd cgroup driver for containerd
      ansible.builtin.copy:
        backup: true
        src: "{{ lookup('env', 'GITHUB_WORKSPACE') }}/config.toml"
        dest: /etc/containerd/config.toml

    - name: Restart containerd and daemon-reload to update config
      ansible.builtin.systemd:
        name: containerd
        daemon_reload: yes
        state: started
        enabled: yes

    - name: Install kubelet, kubeadm, kubectl
      apt:
        name:
          - kubelet
          - kubeadm
          - kubectl
        state: present

    - name: Hold kubectl,kubeadm,kubelet versions
      ansible.builtin.shell: apt-mark hold kubelet kubectl kubeadm
    
- name: Configure the master node
  hosts: master
  become: true
  tasks:    
  - name: Init kubeadm
    ansible.builtin.shell: sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint "{{ansible_host}}:6443"

  - name: Create ~/.kube directory
    ansible.builtin.file:
      path: ~/.kube
      state: directory
      mode: "0755"

  - name: Copy kubeconfig file
    shell: sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

  - name: Set permission on kubeconfig file
    shell: sudo chown $(id -u):$(id -g) $HOME/.kube/config

  - name: Install weavenet pod network add-on
    ansible.builtin.shell: kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

  - name: Generate token to join worker nodes to cluster
    ansible.builtin.shell: sudo kubeadm token create --print-join-command
    register: join_node_token
    delegate_to: master

- name: Join worker nodes to cluster
  hosts: workernode
  become: true
  tasks:
    - name: Save join token command as variable
      ansible.builtin.set_fact:
         join_node: "{{ hostvars['master'].join_node_token.stdout_lines[0] }}"
    - name: Add worker nodes to cluster
      shell: "sudo {{ join_node }}"

So the apt task “Install kubelet, kubeadm, kubectl” fails, but the previous apt tasks succeeded?

Yes previous tasks are succeeded and Installing kubelet, kubeadm, kubectl are failing because of lock on `/var/lib/dpkg/lock-frontend.

Take a look at the tactics used in this post, and see if you can use some of them. In particular, there’s a guy that makes the playbook wait until the lock becomes available.