{"id":3555,"date":"2022-11-16T13:59:15","date_gmt":"2022-11-16T13:59:15","guid":{"rendered":"https:\/\/www.checkmateq.com\/blog\/?p=3555"},"modified":"2024-10-19T17:20:45","modified_gmt":"2024-10-19T17:20:45","slug":"ansible-kubernetes","status":"publish","type":"post","link":"https:\/\/www.checkmateq.com\/blog\/ansible-kubernetes","title":{"rendered":"Ansible Script to create Kubernetes Cluster"},"content":{"rendered":"<p>Ansible is a configuration management tool for used to automation, system configuration management, package management, automate provisioning operations and handle more complex SRE management operations such as automated infrastructure deployment, <a href=\"https:\/\/www.checkmateq.com\/devops-engineering\">patch management<\/a>, server reboot sanitary checks, OS upgrades and package deployment, with pre-defined YAML language written playbook. Ansible can be easily integrated with Jenkins release pipeline as part of continuous integration or continuous deployments pipeline.<\/p>\n<p>In this Ansible blog, we use ansible to create a <a href=\"https:\/\/www.checkmateq.com\/kubernetes\">Kubernetes cluster<\/a> on <a href=\"https:\/\/www.checkmateq.com\/cloud\">AWS cloud<\/a> EC2 instances. We will create 1 control node and 2 worker nodes. We will install all the packages and dependencies using ansible playbooks.<\/p>\n<h3>Prerequisites:<\/h3>\n<ul>\n<li>Host server running with Ansible installed.<\/li>\n<li>ssh-key pair set up to connect to Kubernetes master and worker nodes.<\/li>\n<\/ul>\n<p><strong>Step1: Setup inventory file<\/strong><\/p>\n<ul>\n<li>Add master and worker nodes in the hosts file.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-3564\" src=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company-300x57.png\" alt=\"\" width=\"705\" height=\"134\" srcset=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company-300x57.png 300w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company-1024x194.png 1024w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company-768x145.png 768w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company-1200x227.png 1200w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/database-management-company.png 1384w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/p>\n<ul>\n<li>Ping all nodes to make sure you can connect to them.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-3565\" src=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/web-development-agencies-300x166.png\" alt=\"Ansible script\" width=\"703\" height=\"389\" srcset=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/web-development-agencies-300x166.png 300w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/web-development-agencies-768x425.png 768w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/web-development-agencies.png 945w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/p>\n<h3>Ste2: Set up a user on nodes<\/h3>\n<ul>\n<li>Next, we will set up a non-root user with sudo permissions on the master and worker nodes so that we can manage the cluster safely.<\/li>\n<li>Create an ansible playbook and copy the following code there.<\/li>\n<\/ul>\n<pre><code>\r\n\r\n- hosts: all\r\n  become: yes\r\n  tasks:\r\n    - name: create the 'k8sadmin' user\r\n      user:\r\n        name: k8sadmin\r\n        append: yes\r\n        state: present\r\n        createhome: yes\r\n        shell: \/bin\/bash\r\n\r\n    - name: allow 'k8sadmin' sudo permission\r\n      lineinfile:\r\n        dest: \/etc\/sudoers\r\n        line: 'k8sadmin ALL=(ALL) NOPASSWD: ALL'\r\n        validate: 'visudo -cf %s'\r\n\r\n    - name: set authorized keys for the k8sadmin user\r\n      authorized_key:\r\n        user: k8sadmin\r\n        key: \"{{item}}\"\r\n      with_file:\r\n        - ~\/.ssh\/id_rsa.pub\r\n                                               \r\n<\/code><\/pre>\n<ul>\n<li>Run this playbook to create users on all remote nodes.<\/li>\n<\/ul>\n<h3>Step3: Install CRI-O runtime and other Kubernetes dependencies on all nodes<\/h3>\n<ul>\n<li>Create a playbook for installing dependencies and paste the following code there.<\/li>\n<\/ul>\n<pre><code>\r\n- hosts: all\r\n  become: yes\r\n  become_user: root\r\n  gather_facts: yes\r\n\r\n  tasks:\r\n     - name: Create CRI-O config file\r\n       file:\r\n         path: \"\/etc\/modules-load.d\/crio.conf\"\r\n         state: \"touch\"\r\n\r\n     - name: add modules in conf file\r\n       blockinfile:\r\n         path: \"\/etc\/modules-load.d\/crio.conf\"\r\n         block: |\r\n            overlay\r\n            br_netfilter\r\n\r\n     - name: Enable sysctl params\r\n       file:\r\n         path: \"\/etc\/sysctl.d\/99-kubernetes-cri.conf\"\r\n         state: \"touch\"\r\n\r\n     - name: add configuration\r\n       blockinfile:\r\n         path: \"\/etc\/sysctl.d\/99-kubernetes-cri.conf\"\r\n         block: |\r\n                net.bridge.bridge-nf-call-iptables = 1\r\n                net.ipv4.ip_forward = 1\r\n                net.bridge.bridge-nf-call-ip6tables = 1\r\n\r\n     - name: enable overlayFS &amp; VxLan pod communication\r\n       shell: |\r\n               sudo modprobe overlay\r\n               sudo modprobe br_netfilter\r\n     - name: Reload parameters\r\n       command: sudo sysctl --system\r\n\r\n     - name: disable swap\r\n       shell: |\r\n               sudo swapoff -a\r\n               sudo sed -i '\/ swap \/ s\/^\\(.*\\)$\/#\\1\/g' \/etc\/fstab\r\n     - name: enable cri-repo\r\n       environment:\r\n          OS: xUbuntu_20.04\r\n          VERSION: 1.23\r\n       shell: |\r\n                echo \"deb https:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable\/$OS\/ \/\" &gt; \/etc\/apt\/sources.list.d\/devel:kubic:libcontainers:stable.list\r\n                echo \"deb http:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable:\/cri-o:\/$VERSION\/$OS\/ \/\" &gt; \/etc\/apt\/sources.list.d\/devel:kubic:libcontainers:stable:cri-o:$VERSION.list\r\n\r\n                curl -L https:\/\/download.opensuse.org\/repositories\/devel:kubic:libcontainers:stable:cri-o:$VERSION\/$OS\/Release.key | apt-key add -\r\n                curl -L https:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable\/$OS\/Release.key | apt-key add -\r\n     - name: Install cri-o and cri-o tools\r\n       shell: |\r\n               sudo apt-get update\r\n               sudo apt-get install cri-o cri-o-runc cri-tools -y\r\n               sudo systemctl daemon-reload\r\n               sudo systemctl enable crio --now\r\n\r\n     - name: Install dependencies\r\n       shell: |\r\n               sudo apt-get update\r\n               sudo apt-get install -y apt-transport-https curl\r\n               curl -s https:\/\/packages.cloud.google.com\/apt\/doc\/apt-key.gpg | sudo apt-key add -\r\n     - name: Create kubernetes repo file\r\n       file:\r\n         path: \"\/etc\/apt\/sources.list.d\/kubernetes.list\"\r\n         state: \"touch\"\r\n\r\n     - name: Add K8s Source\r\n       blockinfile:\r\n         path: \"\/etc\/apt\/sources.list.d\/kubernetes.list\"\r\n         block: |\r\n               deb https:\/\/apt.kubernetes.io\/ kubernetes-xenial main\r\n\r\n     - name: install kubernetes\r\n       shell: |\r\n               sudo apt-get update\r\n               sudo apt-get install -y kubelet=1.23.1-00 kubeadm=1.23.1-00 kubectl=1.23.1-00\r\n               sudo apt-mark hold kubelet kubeadm kubectl\r\n\r\n\r\n<\/code><\/pre>\n<h3>Step4: Initialize kubeadm on the master node<\/h3>\n<ul>\n<li>Next we will initialize the cluster using kubeadm init command on contrrol plane.<\/li>\n<li>Then we will print the join yoken and copy it to ansible host.<\/li>\n<\/ul>\n<pre><code>\r\n- hosts: master\r\n  become: yes\r\n  tasks:\r\n    - name: initialize the cluster\r\n      shell: sudo kubeadm init --pod-network-cidr=192.168.0.0\/16  --cri-socket=\/var\/run\/crio\/crio.sock  --ignore-preflight-errors Swap &gt;&gt; cluster_initialized.txt\r\n      args:\r\n        chdir: $HOME\r\n        creates: cluster_initialized.txt\r\n\r\n    - name: create .kube directory\r\n      become: yes\r\n      become_user: k8sadmin\r\n      file:\r\n        path: \/home\/k8sadmin\/.kube\r\n        state: directory\r\n        mode: 0755\r\n\r\n    - name: copy admin.conf\r\n      copy:\r\n        remote_src: yes\r\n        src: \/etc\/kubernetes\/admin.conf\r\n        dest: \/home\/k8sadmin\/.kube\/config\r\n        owner: k8sadmin\r\n\r\n    - name: Install calico Pod network\r\n      become: yes\r\n      become_user: k8sadmin\r\n      shell:  kubectl apply -f https:\/\/docs.projectcalico.org\/manifests\/calico.yaml\r\n      args:\r\n        chdir: $HOME\r\n\r\n\r\n    - name: Get join token\r\n      become: yes\r\n      become_user: k8sadmin\r\n      shell: sudo kubeadm token create  --print-join-command\r\n      register: kubernetes_join_command\r\n\r\n    - name: Copy join command to local file.\r\n      become: yes\r\n      local_action: copy content=\"{{ kubernetes_join_command.stdout_lines[0] }}\" dest=\"\/tmp\/kubernetes_join_command\" mode=0777\r\n<\/code><\/pre>\n<h3>Step4: Set up worker nodes<\/h3>\n<ul>\n<li>Now we will copy the join command to worker nodes from the ansible host and execute it.<\/li>\n<\/ul>\n<pre><code>\r\n- hosts: workers\r\n  become: yes\r\n  gather_facts: yes\r\n\r\n  tasks:\r\n   - name: Copy join command from Ansiblehost to the worker nodes.\r\n     become: yes\r\n     copy:\r\n       src: \/tmp\/kubernetes_join_command\r\n       dest: \/tmp\/kubernetes_join_command\r\n       mode: 0777\r\n\r\n   - name: Join the Worker nodes to the cluster.\r\n     become: yes\r\n     command: sh \/tmp\/kubernetes_join_command\r\n     register: joined_or_not                                             \r\n<\/code><\/pre>\n<ul>\n<li>Now ssh to the master node and verify that nodes are ready.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-3573\" src=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/Checkmate-AWS-cloud-services-300x45.png\" alt=\"\" width=\"733\" height=\"110\" srcset=\"https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/Checkmate-AWS-cloud-services-300x45.png 300w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/Checkmate-AWS-cloud-services-1024x153.png 1024w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/Checkmate-AWS-cloud-services-768x115.png 768w, https:\/\/www.checkmateq.com\/blog\/wp-content\/uploads\/2022\/11\/Checkmate-AWS-cloud-services.png 1128w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/p>\n<p>Author Details<\/p>\n<p>This blog is Written by Amit Kumar, Head of Engineering, at Checkmate Management Consulting. Please reach to him for <a href=\"https:\/\/www.checkmateq.com\/aws-cloud\">Cloud engineering infrastructure<\/a> best practices, <a href=\"https:\/\/www.checkmateq.com\/hire-developer\">Hire Software Developer in India<\/a>,\u00a0 <a href=\"https:\/\/www.checkmateq.com\/hire-developer\">IT Staff Augmentation Services<\/a>, Remote <a href=\"https:\/\/www.checkmateq.com\/virtual-cto-services\">Virtual CTO Services<\/a> and infuse <a href=\"https:\/\/www.checkmateq.com\/cloud\">cloud support<\/a> best practices to stable daily production operation and <a href=\"https:\/\/www.checkmateq.com\/technology-consulting\">Technology Consulting Services<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ansible is a configuration management tool for used to automation, system configuration management, package management, automate provisioning operations and handle more complex SRE management operations such as automated infrastructure deployment, patch management, server reboot sanitary checks, OS upgrades and package deployment, with pre-defined YAML language written playbook. Ansible can be easily integrated with Jenkins release &hellip; <a href=\"https:\/\/www.checkmateq.com\/blog\/ansible-kubernetes\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Ansible Script to create Kubernetes Cluster&#8221;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":3602,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[2,71,70,69,68,7,6],"_links":{"self":[{"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/posts\/3555"}],"collection":[{"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/comments?post=3555"}],"version-history":[{"count":21,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/posts\/3555\/revisions"}],"predecessor-version":[{"id":4623,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/posts\/3555\/revisions\/4623"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/media\/3602"}],"wp:attachment":[{"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/media?parent=3555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/categories?post=3555"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.checkmateq.com\/blog\/wp-json\/wp\/v2\/tags?post=3555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}