sudo for Windows

In Windows, with the use of powershell, at some point in time you will feel the need to elevate the privileges while in the same terminal, akin to sudo in Linux. Two options are mentioned below.

Using runas verb as below. This launches a new window.

start-process PowerShell -verb runas

Using gsudo from here, which is my personal favorite. Install it using below command.

winget install gerardog.gsudo

Once installed it can be used like below:

gsudo notepad

Kubectl installation on Windows

I found it easier to keep executable files that are not managed by Windows itself in a custom folders at “C:\Program Files (Folder)”. Executables are placed under their individual folder, path to which gets added to the Windows machine’s Path variable.

Find the latest version of kubectl from here. CD into the folder where you would like to store the kubectl executable. Keep in mind, this folder will be added to Windows machine’s path variable. In the current example this will be at “C:\Program Files (Folder)\Kubernetes”. Follow the commands below to create the folder and download kubectl.

c:\
c:\mkdir "Program Files (Folder)"
c:\cd "Program Files (Folder)"
c:\Program Files (Folder)\mkdir Kubernetes
c:\Program Files (Folder)\cd Kubernetes
c:\Program Files (Folder)\Kubernetes\

Once in the folder use the command below to download the desired version of kubectl. Replace {VERSION} with the desired version.

curl -LO "https://dl.k8s.io/release/{VERSION}/bin/windows/amd64/kubectl.exe"

Also download the checksum file using the command below.

curl -LO "https://dl.k8s.io/{VERSION}/bin/windows/amd64/kubectl.exe.sha256"

validate the executable against the checksum.

Manually:

c:\Program Files (Folder)\Kubernetes\CertUtil -hashfile kubectl.exe SHA256
c:\Program Files (Folder)\Kubernetes\type kubectl.exe.sha256

Using powershell:

$($(CertUtil -hashfile .\kubectl.exe SHA256)[1] -replace " ", "") -eq $(type .\kubectl.exe.sha256)

Once verified add the kubectl folder path to the machine’s Path variable using the command below. This requires elevated privileges.

[Environment]::SetEnvironmentVariable("Path", "$($env:path);c:\Program Files (Folder)\Kubernetes", [System.EnvironmentVariableTarget]::Machine)

Reload the Path environment variable.

$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine")

At this point you should be able to use kubectl to manage your kubernetes cluster. Make sure your user profile folder has a .kube directory and a valid kubernetes cluster config file inside it.

WSL Issues

How to fix “Access is denied” error when starting WSL?

Shutdown WSL using the following command in any terminal. Don’t worry, this will NOT shutdown your windows PC.

wsl --shutdown

Once the above command returns, start bash as administrator. WSL should greet you with Linux prompt.

How to upgrade WSL – Ubuntu LTS Linux distribution?

Update and upgrade apt repositories using commands below.

sudo apt update
sudo apt upgrade

Check availability of upgrade using the command below.

sudo do-release-upgrade -c

If upgrade is available, upgrade using the command below.

sudo do-release-upgrade

If for some reason it does not work, try with -p option like below.

sudo do-release-upgrade -p

To see what options available using the upgrade tool, run the command below.

sudo do-release-upgrade --help

How to fix “Restoring original system state. Aborting” error when upgrading WSL – Ubuntu distribution?

Sometimes, when upgrading the Linux distribution, the upgrade fails silently with the below messages.

Restoring original system state

Aborting
Reading package lists... Done    
Building dependency tree          
Reading state information... Done

See why the upgrades are failing by running the following command.

cat /var/log/dist-upgrade/main.log

Most likely, snapd and screen are causing the upgrade to fail. Remove these programs by running the below commands.

sudo apt purge snapd

sudo apt purge screen

If this is not the reason upgrades are failing, check the log and resolve any other issue that is reported in the log. Once all the issues are resolve, the release upgrade should complete successfully.

Postgres database corruption errors

There are times due to one reason or other Postgres database might report errors like below:

invalid page in block 1 of relation base/*/*

This indicates the one of the databases on the server was corrupted due to mostly a hardware failure e.g. bad sectors in a hard disk. It is always better to try to recover the data or repair the hard disk as soon as this is detected; the chances to recover the data decreases over time. Follow the steps below to recover the databases with as little data loss as possible.

  • Login to the postgresql cli
  • Run the below code one after the other
    • SET zero_damaged_pages=on;
    • VACUUM FULL;
    • VACUUM FREEZE;
    • REINDEX database databasename;

When you run VACCUM commands below warnings will show once the bad sector/data is encountered.

WARNING:  invalid page in block 1 of relation base/*/*; zeroing out page
ERROR:  index "indexname" contains unexpected zero page at block 1
HINT:  Please REINDEX it.

Once the reindex step mentioned above is run, this will fix itself.

Repeat the process for all the databases on the server. Once complete the Postgres database should be back online with minimal data loses.

Below are few advanced articles you can follow to have more granular control of the recovery process.

Tracking Down Database Corruption With psql.

S6: Invalid page / page verification failed (data corrupted)

Replacing Bad Hard Drive in Linux

This is an eventual possibility that one has to deal with someday when dealing with self maintained Linux systems. Due to many possible reasons a hard drive may develop unrecoverable bad sectors. The easiest approach to the solution is described here, not to mention that you have to be a little lucky for the drive to not fail on you in its totality.

If you want to try out your luck, please follow below steps:

  • Buy a new hard drive of equal or greater specifications.
  • Create a USB flash drive or USB hard drive for Clonezilla following instructions given here.
  • Shutdown the system.
  • Connect the new hard drive to the system. Do not remove the bad hard drive yet, as we are going to use that as a source for cloning the disks/partitions to the new hard drive.
  • Now connect the Clonezilla live USB hard drive to the system and boot.
  • System will boot into Clonezilla.
  • Follow the guidelines and select device to device or disk to disk path.
  • On the source disk/partition option select the old bad hard drive/partition.
  • On the destination disk/partition option select the new hard drive/partition.
  • Make selections based on your preference on next few steps.
  • Start the cloning process.
  • This will complete successfully, if Clonezilla reports bad sectors and cannot clone a particular partition, do not worry yet, let the process complete. Clonezilla will now suggest running the command with rescue option.
  • Restart Clonezilla and follow the same process (except now you can select the particular partition that failed in the previous step instead of the whole disk), but on the confirmation step at last, after every option was supplied, select NO to proceed. Clonezilla will save a file with the command it created.
  • Given an option to go to Clonezilla command line, go there.
  • Copy the command that is saved in the file and append the –rescue option and run the command.
  • Clonezilla will report warnings but will complete successfully.
  • Once Clonezilla completes, shutdown the system and remove the Clonezilla USB hard drive from the system.
  • Remove the old bad hard drive from the system.
  • Reboot.
  • The system should now have a valid and good hard drive with few missing data. This is at least a better option when you have to choose between entire loss versus loosing a little.

One of the helpful articles about finding bad sectors on a hard disk is referred below.

How to Check Bad Sectors or Bad Blocks on Hard Disk in Linux?

Upgrading Gitlab on Debian: from stretch to buster

The one thing I most admire about Gitlab is its installation experience. The upgrades went through very smoothly all the time. This time though when I did “apt update” and “apt upgrade” it gave the following error message.

Err:7 https://packages.gitlab.com/gitlab/gitlab-ee/debian stretch InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3F01618A51312F3F
.....
.....
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://packages.gitlab.com/gitlab/gitlab-ee/debian stretch InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3F01618A51312F3F
W: Failed to fetch https://packages.gitlab.com/gitlab/gitlab-ee/debian/dists/stretch/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3F01618A51312F3F
W: Some index files failed to download. They have been ignored, or old ones used instead.

Based on the error and after exploring Gitlab installation page for Debian here, it was clear that the repository for gitlab needed to be updated. Only the step 2(Add the GitLab package repository and install the package) in that guide has to be executed.

Once the execution of the “script.deb.sh” completes, running apt upgrade did the rest. Gitlab is now upgrade to version 12.9.3.

Linux: Setting static IPv4 address using terminal

Once logged into the linux machine, edit /etc/network/interfaces file using your favorite text editor. You would see something like this at the end of the file:

iface eno1 inet dhcp

Change the content of this line to say static instead of dhcp. Also add the other parameters as shown in the below code.

iface eno1 inet static
    address 192.168.1.10
    gateway 192.168.1.1
    netmask 255.255.255.0
    dns-nameservers 192.168.1.1

Additionally to set IPv6 address to auto after the above set of lines as shown below.

iface eno1 inet6 auto

Save and exit the editor. Reboot the system.

Kubernetes cluster using Debian Buster on bare metal

This article is based on two separate articles that are found article 1 and article 2. The former describes using Ansible how to create a three node bare metal cluster(one master and two workers) on Debian Stretch. The later talks about creating a single node Kubernetes cluster on Debian Buster. This article is about using techniques and procedures from both of those articles and few instructions from Kubernetes current documentation to create a three node cluster(one master and two workers) using Debian Buster.

Steps to be followed:

  1. Install Debian Buster
  2. Install Kubernetes dependencies
  3. Perform Kubernetes configuration

Download and install Debian Buster in three bare metal boxes. In the component selection dialog make sure to check SSH server component. The setup that was performed for this article also excluded installing any desktop environment components. Once the installation is complete, configure static network by updating /etc/network/interfaces file.

On the local system(Linux or WSL) configure password less remote access to these three servers using these instructions. Install Ansible if is not already installed on the local system. Prepare the inventory list in a file called hosts as described in article 1. This file will list the master and the worker systems.

Create files initial.yml, kube-dependencies.yml, master.yml and workers.yml as described in the article 1 referred in this post. In kube-dependencies.yml make sure to update the Kubernetes version to the latest supported version under release notes and version skew section here. In the master.yml file update the url under install pod network(flannel) to the latest file location here.

Create a kube-firewall.yml file like below. This refers to the article 2 referred in this post. For more information Kubernetes documentation can also be referred.

- hosts: all
  become: yes
  tasks:
   - name: install ufw
     apt:
       name: ufw
       state: present
       update_cache: true

   - name: Enable UFW
     ufw:
       state: enabled

   - name: Allow all ssh access
     ufw:
       rule: limit
       port: ssh
       proto: tcp

   - name: Allow all access to tcp port 10251
     ufw:
       rule: allow
       port: '10251'
       proto: tcp

   - name: Allow all access to tcp port 10255
     ufw:
       rule: allow
       port: '10255'
       proto: tcp

- hosts: master
  become: yes
  tasks:

   - name: Allow all access to tcp port 6443
     ufw:
       rule: allow
       port: '6443'
       proto: tcp

   - name: Allow all access to tcp port 2379
     ufw:
       rule: allow
       port: '2379'
       proto: tcp

   - name: Allow all access to tcp port 2380
     ufw:
       rule: allow
       port: '2380'
       proto: tcp

   - name: Allow all access to tcp port 10250
     ufw:
       rule: allow
       port: '10250'
       proto: tcp

   - name: Allow all access to tcp port 10252
     ufw:
       rule: allow
       port: '10252'
       proto: tcp

Create a kube-flannel-firewall.yml file as specified below. This opens up firewall port for flannel network add on as being instructed here.

- hosts: all
  become: yes
  tasks:

   - name: Allow all access to tcp port 8285
     ufw:
       rule: allow
       port: '8285'
       proto: udp

   - name: Allow all access to tcp port 8472
     ufw:
       rule: allow
       port: '8472'
       proto: udp

Create a kube-nodeport-firewall.yml to open up node ports in the cluster. Please refer to the Kubernetes documentation here for more explanation.

- hosts: all
  become: yes
  tasks:

   - name: Allow all access to tcp port 30000-32767
     ufw:
       rule: allow
       port: 30000:32767
       proto: tcp

Now execute the files using Ansible in the below order. For examples how to execute ansible scripts refer to the article 1.

  1. initial.yml
  2. kube-dependencies.yml
  3. master.yml
  4. workers.yml
  5. kube-firewall.yml
  6. kube-flannel-firewall.yml
  7. kube-nodeport-firewall.yml

At this time due to reasons specified in this section, the Kubernetes executables has to be marked hold. Log in to each box and run the below command.

$ sudo apt-mark hold kubelet kubeadm kubectl

At this time the Kubernetes cluster should be ready. This can be checked by logging into the master node and running kubectl get nodes command. If this shows anything else than ready more troubleshooting information including logs can be found in this article. Also this section in Kubernetes documentation can help.

To understand Kubernetes architecture in detail I would recommend this article here.