<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jean B.</title>
    <description>The latest articles on DEV Community by Jean B. (@jeanb).</description>
    <link>https://dev.to/jeanb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2164083%2F2a7a8afe-f65a-46b3-9dbc-1eaf55f137e1.png</url>
      <title>DEV Community: Jean B.</title>
      <link>https://dev.to/jeanb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeanb"/>
    <language>en</language>
    <item>
      <title>Setting Up a Kubernetes Bare Metal Cluster on Ubuntu</title>
      <dc:creator>Jean B.</dc:creator>
      <pubDate>Fri, 04 Oct 2024 04:48:39 +0000</pubDate>
      <link>https://dev.to/jeanb/setting-up-a-kubernetes-bare-metal-cluster-on-ubuntu-33k8</link>
      <guid>https://dev.to/jeanb/setting-up-a-kubernetes-bare-metal-cluster-on-ubuntu-33k8</guid>
      <description>&lt;p&gt;In this guide, we will walk through the steps to set up a Kubernetes cluster on bare metal servers running Ubuntu. This guide covers the installation of necessary tools, configuration of the master and worker nodes, and setting up network and storage solutions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fig0mcltjaet7j28m47sj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fig0mcltjaet7j28m47sj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Machine Requirements
&lt;/h2&gt;

&lt;p&gt;To set up the Kubernetes cluster, you will need the following machines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 Master Node on Ubuntu&lt;/li&gt;
&lt;li&gt;3 Worker Nodes on Ubuntu&lt;/li&gt;
&lt;li&gt;1 NFS host on Ubuntu&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Install SSH Server and Net-tools
&lt;/h2&gt;

&lt;p&gt;First, ensure that SSH server and net-tools are installed on all machines. This will allow you to remotely manage the servers and check network configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;openssh-server
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status ssh
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;net-tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Cluster Volume Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Objectives:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install NFS Server on a separate host&lt;/li&gt;
&lt;li&gt;Install NFS client on all Kubernetes cluster nodes&lt;/li&gt;
&lt;li&gt;Test if all clients are connected to the NFS host&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  NFS Installation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  i. On NFS Host Machine
&lt;/h4&gt;

&lt;p&gt;Update system packages and install the NFS server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nfs-kernel-server 
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/nfs_share 
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; nobody:nogroup /mnt/nfs_share/ 
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;777 /mnt/nfs_share/ 
&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/exports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ii. Grant Access to Clients
&lt;/h4&gt;

&lt;p&gt;Configure the NFS server to allow access from the client machines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/mnt/nfs_share &amp;lt;nfs_host_ip&amp;gt;/24&lt;span class="o"&gt;(&lt;/span&gt;rw,sync,no_subtree_check&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;span class="nb"&gt;sudo &lt;/span&gt;exportfs &lt;span class="nt"&gt;-a&lt;/span&gt; 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nfs-kernel-server
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow from &amp;lt;nfs_host_ip&amp;gt;/20 to any port nfs 
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable 
sudo &lt;/span&gt;ufw status 
&lt;span class="nb"&gt;cd&lt;/span&gt; /mnt/nfs_share/ 
&lt;span class="nb"&gt;touch &lt;/span&gt;sample1.text sample2.text 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  iii. &amp;amp; iv. On NFS Client Machines
&lt;/h4&gt;

&lt;p&gt;Install the NFS client and mount the shared directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update  
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nfs-common 
&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/nfs_clientshare 
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &amp;lt;nfs_host_ip&amp;gt;:/mnt/nfs_share /mnt/nfs_clientshare 
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /mnt/nfs_clientshare/ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Master Node Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  i. Assign Static IP and Update Machine
&lt;/h3&gt;

&lt;p&gt;If the machine IP is not static, assign a static IP and update the machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/netplan/00-installer-config.yaml
network: 
  ethernets: 
    enp0s3: 
      dhcp4: &lt;span class="nb"&gt;true 
    &lt;/span&gt;enp0s8: 
      addresses: &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;master_node_ip&amp;gt;/20]
  version: 2 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the changes and reboot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;netplan apply 
&lt;span class="nb"&gt;sudo &lt;/span&gt;shutdown &lt;span class="nt"&gt;-r&lt;/span&gt; now 
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;  
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; full-upgrade 
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/run/reboot-required &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot –f 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ii. Install Kubernetes Tools
&lt;/h3&gt;

&lt;p&gt;Install kubelet, kubeadm, and kubectl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; apt-transport-https ca-certificates curl gpg
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/keyrings/kubernetes-apt-keyring.gpg
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/kubernetes.list
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;vim git curl wget kubelet kubeadm kubectl 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-mark hold kubelet kubeadm kubectl 
kubectl version &lt;span class="nt"&gt;--client&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; kubeadm version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  iii. Disable Swap
&lt;/h3&gt;

&lt;p&gt;Disable swap to ensure Kubernetes runs smoothly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/ swap / s/^\(.*\)$/#\1/g'&lt;/span&gt; /etc/fstab 
&lt;span class="nb"&gt;sudo &lt;/span&gt;swapoff &lt;span class="nt"&gt;-a&lt;/span&gt; 
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt; 
free –h 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable kernel modules and configure IP tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;modprobe overlay 
&lt;span class="nb"&gt;sudo &lt;/span&gt;modprobe br_netfilter 
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/sysctl.d/kubernetes.conf&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; 
net.bridge.bridge-nf-call-ip6tables = 1 
net.bridge.bridge-nf-call-iptables = 1 
net.ipv4.ip_forward = 1 
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;--system&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  iv. Install CRI-O
&lt;/h3&gt;

&lt;p&gt;Install the Container Runtime Interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reboot
&lt;span class="nv"&gt;OS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xUbuntu_20.04 
&lt;span class="nv"&gt;CRIO_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.23 
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/&lt;/span&gt;&lt;span class="nv"&gt;$OS&lt;/span&gt;&lt;span class="s2"&gt;/ /"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list 
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/&lt;/span&gt;&lt;span class="nv"&gt;$CRIO_VERSION&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$OS&lt;/span&gt;&lt;span class="s2"&gt;/ /"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:&lt;span class="nv"&gt;$CRIO_VERSION&lt;/span&gt;.list 
curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:&lt;span class="nv"&gt;$CRIO_VERSION&lt;/span&gt;/&lt;span class="nv"&gt;$OS&lt;/span&gt;/Release.key | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add - 
curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/&lt;span class="nv"&gt;$OS&lt;/span&gt;/Release.key | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add - 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;cri-o cri-o-runc 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;crio.service 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start crio.service 
systemctl status crio 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;cri-tools 
&lt;span class="nb"&gt;sudo &lt;/span&gt;crictl info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  v. Install Podman
&lt;/h3&gt;

&lt;p&gt;Install Podman, an alternative to Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;podman
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  vi. Initialize Master Node
&lt;/h3&gt;

&lt;p&gt;Enable kubelet and pull Kubernetes container images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;lsmod | &lt;span class="nb"&gt;grep &lt;/span&gt;br_netfilter 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;kubelet 
&lt;span class="nb"&gt;sudo &lt;/span&gt;kubeadm config images pull &lt;span class="nt"&gt;--cri-socket&lt;/span&gt; unix:///var/run/crio/crio.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  vii. Spin Up Master Node Pods
&lt;/h3&gt;

&lt;p&gt;Initialize the master node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;kubeadm init &lt;span class="nt"&gt;--apiserver-advertise-address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;master_node_ip&amp;gt; &lt;span class="nt"&gt;--pod-network-cidr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;192.168.0.0/16 &lt;span class="nt"&gt;--cri-socket&lt;/span&gt; unix:///var/run/crio/crio.sock &lt;span class="nt"&gt;--upload-certs&lt;/span&gt; &lt;span class="nt"&gt;--control-plane-endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;master_node_ip&amp;gt; &lt;span class="nt"&gt;--v&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expose the master node pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/admin.conf 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  viii. Install Network Plugins
&lt;/h3&gt;

&lt;p&gt;Install network plugins using Calico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml 
kubectl create &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/custom-resources.yaml 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ix. Install HELM
&lt;/h3&gt;

&lt;p&gt;Install HELM for managing Kubernetes applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;snap &lt;span class="nb"&gt;install &lt;/span&gt;helm &lt;span class="nt"&gt;--classic&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  x. Install NFS Subdirectory External Provisioner Helm Chart
&lt;/h3&gt;

&lt;p&gt;Install the NFS subdirectory external provisioner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ 
helm &lt;span class="nb"&gt;install &lt;/span&gt;nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner &lt;span class="nt"&gt;--set&lt;/span&gt; nfs.server&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;nfs_host_ip&amp;gt; &lt;span class="nt"&gt;--set&lt;/span&gt; nfs.path&lt;span class="o"&gt;=&lt;/span&gt;/mnt/nfs_share
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  xi. Install and Configure External IP Service
&lt;/h3&gt;

&lt;p&gt;Create a config.yaml file for the external IP service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration (replace xxx with your IP range):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apiVersion: v1 
kind: ConfigMap 
metadata: 
  namespace: metallb-system 
  name: config 
data: 
  config: | 
    address-pools: 
    - name: my-ip-space 
      protocol: layer2 
      addresses: 
      - xxx.xxx.xxx.210-xxx.xxx.xxx.250
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml 
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml 
kubectl create secret generic &lt;span class="nt"&gt;-n&lt;/span&gt; metallb-system memberlist &lt;span class="nt"&gt;--from-literal&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;secretkey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 128&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
kubectl get configmap kube-proxy &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="nt"&gt;-o&lt;/span&gt; yaml | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"s/strictARP: false/strictARP: true/"&lt;/span&gt; | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; - &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system 
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Worker Node Setup
&lt;/h2&gt;

&lt;p&gt;Follow steps i to v of the master node setup on each worker node. Then, join the worker nodes to the master node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes 
kubeadm token generate 
kubeadm token create &amp;lt;token&amp;gt; &lt;span class="nt"&gt;--print-join-command&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the join command on each worker node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubeadm &lt;span class="nb"&gt;join&lt;/span&gt; &amp;lt;master_node_ip&amp;gt;:6443 &lt;span class="nt"&gt;--token&lt;/span&gt; &amp;lt;token&amp;gt; &lt;span class="nt"&gt;--discovery-token-ca-cert-hash&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Install Ingress via HELM
&lt;/h2&gt;

&lt;p&gt;Install the NGINX Ingress controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace ingress-nginx
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm &lt;span class="nb"&gt;install &lt;/span&gt;nginx-ingress ingress-nginx/ingress-nginx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; ingress-nginx &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; controller.replicaCount&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; controller.nodeSelector.&lt;span class="s2"&gt;"kubernetes&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;io/os"&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Create Persistent Volume Profiles
&lt;/h2&gt;

&lt;p&gt;Create a Persistent Volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ClusterPersistentVolume.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apiVersion: v1 
kind: PersistentVolume 
metadata:
  name: dev-pv 
  labels: 
    &lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="nb"&gt;local 
&lt;/span&gt;spec: 
  storageClassName: nfs-client 
  capacity: 
    storage: 50Gi 
  accessModes: 
    - ReadWriteOnce 
  persistentVolumeReclaimPolicy: Retain 
  hostPath: 
    path: /mnt/nfs_share  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get sc 
kubectl apply –f ClusterPersistentVolume.yaml 
kubectl get pv 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a Persistent Volume Claim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ClusterPersistentVolumeClaim.yaml 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apiVersion: v1 
kind: PersistentVolumeClaim 
metadata: 
  name: dev-pvc
spec: 
  storageClassName: nfs-client 
  accessModes: 
    - ReadWriteOnce 
resources: 
  requests: 
    storage: 25Gi 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace dev 
kubectl apply –f ClusterPersistentVolumeClaim.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; dev 
kubectl get pvc –n dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;By following these steps, you will have a fully functional Kubernetes cluster running on bare metal servers. This setup provides a robust environment for deploying and managing containerized applications.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>ubuntu</category>
      <category>devops</category>
    </item>
    <item>
      <title>Setting Up Keycloak with MSSQL Server Using Docker</title>
      <dc:creator>Jean B.</dc:creator>
      <pubDate>Fri, 04 Oct 2024 00:43:43 +0000</pubDate>
      <link>https://dev.to/jeanb/setting-up-keycloak-with-mssql-server-using-docker-3pl1</link>
      <guid>https://dev.to/jeanb/setting-up-keycloak-with-mssql-server-using-docker-3pl1</guid>
      <description>&lt;p&gt;In this guide, I will walk you through setting up &lt;strong&gt;Keycloak&lt;/strong&gt; with &lt;strong&gt;MSSQL Server&lt;/strong&gt; using Docker containers. This setup will allow you to run Keycloak with MSSQL as its backend database, useful for development or integration with other applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, ensure you have Docker installed and running on your system. We'll be pulling images for Keycloak and MSSQL Server and setting up a Docker network to connect both containers.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Pull Docker Images for Keycloak and MSSQL Server
&lt;/h3&gt;

&lt;p&gt;Start by pulling the latest Keycloak and MSSQL Server images from their respective repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull quay.io/keycloak/keycloak:23.0
docker pull mcr.microsoft.com/mssql/server:2019-latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 2: Create a Docker Network
&lt;/h3&gt;

&lt;p&gt;We will create a dedicated Docker network for Keycloak and the MSSQL Server container so they can communicate with each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create keycloak_network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Spin Up MSSQL Server
&lt;/h3&gt;

&lt;p&gt;Next, run the MSSQL Server container. Replace &lt;code&gt;"yourstrongpassword"&lt;/code&gt; with a strong password for the &lt;code&gt;sa&lt;/code&gt; (System Administrator) account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'ACCEPT_EULA=Y'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"MSSQL_SA_PASSWORD=yourstrongpassword"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'MSSQL_RPC_PORT=135'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'MSSQL_DTC_TCP_PORT=51000'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 1433:1433 &lt;span class="nt"&gt;-p&lt;/span&gt; 135:135 &lt;span class="nt"&gt;-p&lt;/span&gt; 51000:51000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--net&lt;/span&gt; keycloak_network &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; sqlserver1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--hostname&lt;/span&gt; sqlserver1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; mcr.microsoft.com/mssql/server:2019-latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4: Connect to the MSSQL Server Container
&lt;/h3&gt;

&lt;p&gt;Once the container is up and running, you can access the container's shell using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; sqlserver1 &lt;span class="s2"&gt;"bash"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Login to the MSSQL server with &lt;code&gt;sqlcmd&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/opt/mssql-tools/bin/sqlcmd &lt;span class="nt"&gt;-S&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; SA &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"yourstrongpassword"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 5: Configure Keycloak Database in MSSQL Server
&lt;/h3&gt;

&lt;p&gt;After logging into the MSSQL server, run the following SQL command to install support for XA transactions (required by Keycloak):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXEC&lt;/span&gt; &lt;span class="n"&gt;sp_sqljdbc_xa_install&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a database for Keycloak:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;keycloak&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;databases&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 6: Run Keycloak Container in Development Mode
&lt;/h3&gt;

&lt;p&gt;Finally, spin up the Keycloak container. Replace the values for &lt;code&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/code&gt; and &lt;code&gt;KC_DB_PASSWORD&lt;/code&gt; with your own strong passwords.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; keycloak_mssql &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;--net&lt;/span&gt; keycloak_network &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;keyadmin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yourkeycloakpass &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mssql &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'jdbc:sqlserver://sqlserver1:1433;instanceName=sqlserver1;databaseName=keycloak;encrypt=false;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sa &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yourstrongpassword &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KC_TRANSACTION_XA_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  quay.io/keycloak/keycloak:23.0 start-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keycloak should now be running in development mode and connected to the MSSQL database. You can access the Keycloak admin console by navigating to &lt;code&gt;http://localhost:8080&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1805bsp77ru8d2du816.PNG" alt="Image description"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;You’ve now set up Keycloak with MSSQL Server as the backend database using Docker. This setup is ideal for development purposes and can easily be extended for production environments by adjusting the configurations. If you run into any issues, make sure to check the logs for both Keycloak and MSSQL Server containers using &lt;code&gt;docker logs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let me know if you found this guide helpful!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>keycloak</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
