How Do You Troubleshoot the “kubectl” Error ‘the server doesn’t have a resource type “svc”‘?

Problem scenario
You are trying to use Kubernetes in AWS.  You have installed kubectl and you run this command:

kubectl get svc

You receive this:  'error: the server doesn't have a resource type "svc"'

You try again with a more verbose output.  You run this command:

kubectl get svc -v=8

In the output you see messages like this: "Response Status: 401 Unauthorized in 73 milliseconds"

What should you do to use kubectl with AWS?

Possible Solution #1
Go to the the .kube directory (e.g., cd ~; cd .kube) and modify the config file. Change the stanza "name: kubernetes" to be "name: NameOfYourCluster" (where "NameOfYourCluster" is the name of your cluster).
Alternatively you could run a command like this: kubectl config set-cluster NameOfYourCluster # where "NameOfYourCluster" is the name of your cluster
If you want more detail, try this posting.

Possible Solution #2
1.  Log into the AWS console:  https://console.aws.amazon.com/eks/home?

2.  Click on the kubernetes cluster you want to obtain more information about (that which you want the kubectl command on the back-end to apply to).  

3.  Find the "Role ARN".  

4.  Go to the Linux server that you run your "kubectl" commands from.  Go to the .kube directory.  Find the config-NameOfCluster file (where "NameOfCluster" is the name of the cluster for which you want to run a kubectl command on).  

5.  In this file make sure your have an "args" section with stanzas such as these (where "arn:aws:iam::123456789:role/nameofcluster" is the value of the 'Role ARN' obtained in step #3):

    - "-r"
    - "arn:aws:iam::123456789:role/nameofcluster"

The two stanzas above are commented out in this thorough explanation of the kubeconfig file: https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html

Possible Solution #3
Install and configure the AWS CLI again; if you need assistance with this, see this posting.  Then create a .kube directory and recreate a kubeconfig file inside this .kube directory by following the directions here:
https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html

Possible Solution #4
Was your Kubernetes cluster created with one user yet your AWS CLI has been configured with a user?  One user can have more than one AWS Access Key.  The problem you are having may be consistent with a different user that created the cluster from the one that is trying to interact with it.  If you can create an access key based on the user that created the cluster, then reconfigure the AWS CLI to use that key, the problem may subside.  Alternatively if you could use the user that you are using to run the "kubectl get svc" command to create a new cluster, that may eliminate the problem too.

How Do You Determine the URL for the AWS Web Console for a Non-root User?

Problem scenario
You created an AWS Console user (e.g., an IAM user).  You want to log into the web UI with the user.  You have the username and password.  What is the URL for the AWS web console for a non-root user?

Solution
1.  Log into the web UI.
2.  Go here: https://console.aws.amazon.com/iam/home?
3.  Go to Users on the left.  
4.  Click on the user you are interested in.
5.  Click on the "Security Credentials" tab near the top.
6.  Near the top the URL should appear.

Is Jenkins job-dsl Different from Jenkinsfile Pipelines’ Scripted Syntax?

Question
You have heard of Jenkins job-dsl.  You are not sure if it is the same DSL found in scripted syntax Jenkinsfile pipelines.  Is Jenkins job-dsl different from Jenkinsfile pipelines' scripted syntax?

Answer
Yes.  Jenkins job-dsl is different from the DSL used in Jenkinsfile pipelines' scripted syntax.  This thread confirms this fact.  This link helps explain the differences.

How Do Quotes Affect Python if Conditional Tests of Equality for a Variable?

Problem scenario
You are programming in Python, and you want to use conditional logic.  You want to know how variables are evaluated and tested.  You want to use the keyword "if" to evaluate a variable assignment.

Solution
This program below shows how the evaluation of a variable in Python behaves when quotes are involved. Errors are not thrown or displayed to the programmer.  Therefore in some instances the programmer must know how quotes affect logical evaluations with variables.

Notice how "testfunc" and "specialfunc" test the variable named "digit" with and without quote marks respectively:


def testfunc(digit):
  if (digit == 0):
    print( "The digit was zero when you called this function")
  else:
    print ("The digit was NOT 0.")

h = testfunc('0')
print ("h with quotes around the zero is above. i with no quotes around the zero is below")
i = testfunc(0)

print( " ")
print( " **************** ")
print( " ")

def specialfunc(digit):
  if (digit == '0'):
    print( "The digit was zero when you called this function")
  else:
    print( "The digit was NOT 0.")

j = specialfunc('0')
print( "j is above with quotes around the zero. k is below with no quotes around the zero.")
k = specialfunc(0)

###Python 3 version above

###Python 2 version below

def testfunc(digit):
  if (digit == 0):
    print "The digit was zero when you called this function"
  else:
    print "The digit was NOT 0."

h = testfunc('0')
print "h with quotes around the zero is above. i with no quotes around the zero is below"
i = testfunc(0)

print " "
print " **************** "
print " "

def specialfunc(digit):
  if (digit == '0'):
    print "The digit was zero when you called this function"
  else:
    print "The digit was NOT 0."

j = specialfunc('0')
print "j is above with quotes around the zero. k is below with no quotes around the zero."
k = specialfunc(0)

The above program prints this:

The digit was NOT 0.
h with quotes around the zero is above. i with no quotes around the zero is below
The digit was zero when you called this function

 ****************

The digit was zero when you called this function
j is above with quotes around the zero. k is below with no quotes around the zero.
The digit was NOT 0.

Given that the only difference between testfunc and specialfunc is the quotes around the 0 in the if clause, you may think that Python is weakly-typed.  There are no errors thrown.  However, Python is strongly typed and dynamically typed.  For more information see this article.

How Do You Iterate through Data Members (the Individual Components) of a Groovy Object?

Problem scenario
You have an object that you want to sequentially pass through.  That is, you want to print either the value or the key/name and value pair of every member data item of the object.  How do you print every individual data member of a given object in Groovy?

Solution
Invoke the ".properties.each" keyword.  This built-in feature will allow you to do just this.  There is one "if" condition you will use to avoid printing the "class=class ..." feature.

Here is an example (the code starts with "@groovy..." and ends with "}"):

@groovy.transform.Canonical
class Program {
    String mem1 = ""
    String mem2 = ""
    String mem3 = ""
    String mem4 = ""
    String mem5 = ""
    String mem6 = ""
    String mem7 = ""
    String mem8 = ""
    String mem9 = ""
}

programsv1 = new Program( "1", "2", "3", "4", "5", "6", "7", "8", "9")

programsv1.properties.each { name, value ->
    if (name != 'class') {
       println "${name}, ${value}" }
     }

If you want it sorted, use the slightly more verbose option of ".sort{ it.key }" in between the "properties" and ".each".  Here is an example:

@groovy.transform.Canonical
class Program {
    String mem1 = ""
    String mem2 = ""
    String mem3 = ""
    String mem4 = ""
    String mem5 = ""
    String mem6 = ""
    String mem7 = ""
    String mem8 = ""
    String mem9 = ""
}

programsv1 = new Program( "1", "2", "3", "4", "5", "6", "7", "8", "9")

programsv1.properties.sort{ it.key }.each { name, value ->
    if (name != 'class') {
       println "${name}, ${value}" }
     }

How Do You SSH to a GCP server?

Problem scenario
You cannot SSH into a Linux Google Cloud Platform server.  How do you create new GCP servers that you can SSH into?

Solution
Summary
Use the "Startup script" in Google Cloud Platform.  This script comes with precautions.  Be careful when pasting it.  The lines can potentially not wrap properly.  Carriage returns could be introduced to make this script fail.  Be very careful because this script creates a user with sudoer privileges.  It also has a plaintext password in it for this user!  This script is for informational purposes.

If you use Puppet for example, the facter tool will be able to retrieve the entire script below after the script below runs.  This is a potential security concern!

This will create two "ChallengeResponseAuthentication yes" stanzas in most Red Hat family servers.  You can manually comment one out.  It will not prevent you from logging on.

Procedures

1.  This solution only works for servers that have not yet been created.  When you create the server, place this script in the "Startup Script" but replace "cooluser" and "coolpassword" with the credentials you want a sudo user to have:

#!/bin/bash
# Written by www.continualintegration.com.  We recommend you modify it in Notepad++.

usr="cooluser"   # change cooluser to the username you want to add
pswd="coolpassword"  # change coolpassword to the password of your choice.
#mkdir /home/$usr   # probably can remove this stanza

distro=$(cat /etc/*-release | grep NAME)

debflag=$(echo $distro | grep -i "ubuntu")
if [ -z "$debflag" ]
then   # If it is not Ubuntu, test if it is Debian.
  debflag=$(echo $distro | grep -i "debian")
  echo "determining Linux distribution..."
else
   echo "You have Ubuntu Linux!"
fi

rhflag=$(echo $distro | grep -i "red*hat")
if [ -z "$rhflag" ]
then   #If it is not RedHat, see if it is CentOS or Fedora.
  rhflag=$(echo $distro | grep -i "centos")
  if [ -z "$rhflag" ]
    then    #If it is neither RedHat nor CentOS, see if it is Fedora.
    echo "It does not appear to be CentOS or RHEL..."
    rhflag=$(echo $distro | grep -i "fedora")
    fi
fi

if [ -z "$rhflag" ]
  then
  echo "...still determining Linux distribution..."
else
  echo "You have a RedHat distribution (e.g., CentOS, RHEL, or Fedora)"
  useradd -m $usr -g wheel
  chown $usr:$usr /home/$usr
  #usermod -aG wheel $usr
fi

if [ -z "$debflag" ]
then
  echo "...still determining Linux distribution..."
else
   echo "You are using either Ubuntu Linux or Debian Linux."
   apt-get -y upgrade gawk
   useradd -m $usr -g sudo
   chown $usr:$usr /home/$usr
   #usermod -aG sudo $usr  # this won't work on a Red Hat family server
fi


suseflag=$(echo $distro | grep -i "suse")
if [ -z "$suseflag" ]
then
  if [ -z "$debflag" ]
  then
    if [ -z "$rhflag" ]
      then
      echo "*******************************************"
      echo "Could not determine the Linux distribution!"
      echo "Installation aborted. Nothing was done."
      echo "******************************************"
      exit
    fi
  fi
else  # This else clause evaluates if you have Linux SUSE.
   echo "Processing steps for Linux SUSE"
   sudo useradd $usr -m -g google-sudoers
   chown $usr:users /home/$usr   
fi

echo $usr:$pswd | chpasswd   

# obtain line numbers f the sshd_config file that need to be changed
pa=$(cat /etc/ssh/sshd_config | grep -n "PasswordAuthentication no" | awk --field-separator=":" '{print $1}')

if [ -z "$pa" ]
  then
      pa=$(cat /etc/ssh/sshd_config | grep -n "PasswordAuthentication yes" | grep "\#" | awk --field-separator=":" '{print $1}')
  fi

cra=$(cat /etc/ssh/sshd_config | grep -n "ChallengeResponseAuthentication no" | awk --field-separator=":" '{print $1}')
if [ -z "$cra" ]
  then
    cra=$(cat /etc/ssh/sshd_config | grep -n "ChallengeResponseAuthentication yes" | grep "\#" | awk --field-separator=":" '{print $1}')
  fi

pa=$(echo $pa | awk '{print $1}')    # get the top line number of the one that matched
cra=$(echo $cra | awk '{print $1}')  # get the top line number of the one that matched

bv=$(date)
bva=${bv//[[:blank:]]/}
bvar=$bva.bak
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.$bvar  #back up the file

part1="sed -i \""$pa"s/PasswordAuthentication no/PasswordAuthentication yes/\" /etc/ssh/sshd_config"
echo $part1 >> /tmp/cool.sh
part2="sed -i \""$pa"s/# PasswordAuthentication no/PasswordAuthentication yes/\" /etc/ssh/sshd_config"
echo $part2 >> /tmp/cool.sh
part3="sed -i \""$pa"s/#PasswordAuthentication no/PasswordAuthentication yes/\" /etc/ssh/sshd_config"
echo $part3 >> /tmp/cool.sh
part4="sed -i \""$pa"s/#PasswordAuthentication yes/PasswordAuthentication yes/\" /etc/ssh/sshd_config"
echo $part4 >> /tmp/cool.sh
part5="sed -i \""$pa"s/# PasswordAuthentication yes/PasswordAuthentication yes/\" /etc/ssh/sshd_config"
echo $part5 >> /tmp/cool.sh
part6="sed -i \""$cra"s/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/\" /etc/ssh/sshd_config"
echo $part6 >> /tmp/cool.sh
part7="sed -i \""$cra"s/#ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/\" /etc/ssh/sshd_config"
echo $part7 >> /tmp/cool.sh
part8="sed -i \""$cra"s/# ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/\" /etc/ssh/sshd_config"
echo $part8 >> /tmp/cool.sh
part9="sed -i \""$cra"s/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication yes/\" /etc/ssh/sshd_config"
echo $part9 >> /tmp/cool.sh
part10="sed -i \""$cra"s/# ChallengeResponseAuthentication yes/ChallengeResponseAuthentication yes/\" /etc/ssh/sshd_config"
echo $part10 >> /tmp/cool.sh

# Modify the /etc/passwd so the new user can use the up arrow to see history of commands entered
thefile="/etc/passwd"
bv=$(date)
bva=${bv//[[:blank:]]/}
bvar=$bva.bak
cp /etc/passwd /etc/bak.passwd.$bvar.bak
ln=$(cat $thefile | grep -n $usr | awk --field-separator=":" '{print $1}')
var2=$var1"/bin/bash/"

ifexists=$usr":/"
flag=$(cat $thefile | grep -n $ifexists)
if [ -z "$flag" ]
then
  sethome="sed -i \""$ln"s/home\/$usr:/home\/$usr:\/bin\/bash/\" $thefile"
  echo $sethome
  echo $sethome >> /tmp/cool.sh
fi

bash /tmp/cool.sh
rm /tmp/cool.sh

echo '
usr="cooluser"
oldfile=$(cat /etc/passwd)
echo "${oldfile//\/home\/$usr:\/bin\/sh/\/home\/$usr:\/bin\/bash}" > /etc/passwd 
' >> /home/result.sh
/bin/bash /home/result.sh
rm /home/result.sh

# For reference only.
#perl -i -pe 's/.*/PasswordAuthentication yes/ if $.==$pa' /etc/ssh/sshd_config file
#perl -i -pe 's/.*/ChallengeResponseAuthentication yes/ if $.==$cra' /etc/ssh/sshd_config file

echo ":set mouse=" >> /home/$usr/.vimrc
echo ":set mouse=" >> /root/.vimrc

systemctl restart sshd   # for Red Hat derivatives b/c the command below will do nothing.

/etc/init.d/ssh restart

2.  After the server is up, in the GCP web console click on the server's name.  This way you can view the details.  Scroll down to the "Custom Metadata" and click on the "X" to eliminate the script as this picture shows:

Scroll down and click "Save".

3.  You are done.

How Do You Troubleshoot “Redirecting to /bin/systemctl start docker.service ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units”?

Problem Scenario
You try to configure Docker such that you can run "docker" commands without sudo.  You run these three commands:

sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker

You then installed Docker and rebooted the server.  You then run this:

docker run hello-world

But you received this:

/usr/bin/docker-current: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See '/usr/bin/docker-current run --help'.

You ran this: sudo service docker status
The results confirmed the Docker was not running.

You ran this: service docker start

But you received this:

Redirecting to /bin/systemctl start docker.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: Cloud User (ec2-user)
Password:

How do you start the docker service without sudo?

Solution
Use this set of directions to configure Docker to work without the sudo command.

How Do You Use docker-compose?

Problem scenario
You want to create an example of a docker compose file.  How do you use docker-compose?

Prerequisites
i.  This assumes you have Docker installed and running.  If you need assistance, see this posting.
ii.  This assumes that you have installed docker-compose.  If you need assistance, see this posting.
iii.  This assumes the Docker host has access to the internet.
iv.  Port 8080 is not being used (e.g., any containers that use this port are turned off).  If you need to keep port 8080 open for another purpose, change the "8080" in the directions below.

Procedures
1.  Run these three commands:

mkdir dockercompose && cd dockercompose
mkdir webapp
echo "<h2>It worked\!</h2>" > webapp/index.html

2.a.  Create a Dockerfile in the webapp directory. (You may want to run vi webapp/Dockerfile.)
2.b.   This is the content for the Dockerfile:

FROM tecadmin/ubuntu-ssh:16.04
RUN apt-get update \
   && apt-get install -y apache2
COPY index.html /var/www/html/
WORKDIR /var/www/html
CMD ["apachectl", "-D", "FOREGROUND"]
EXPOSE 80

3.a.  Create a docker-compose.yml file.  (You may want to run vi docker-compose.yml.)
3.b.  This is the content of the docker-compose.yml file:

version: '3'
services:
  db:
     image: mysql
     container_name: mysql_db
     restart: always
     environment:
        - MYSQL_ROOT_PASSWORD="secret"
  web:
    image: apache
    build: ./webapp
    depends_on:
       - db
    container_name: apache_web
    restart: always
    ports:
      - "8080:80"

4.  Run these commands:  

echo "You just used Docker Compose via ContinualIntegration.com" >> webapp/index.html
docker-compose build
docker-compose up -d

5.  Open a web browser.  Go to x.x.x.x:8080 where x.x.x.x is the external IP address of the server (or the result of curl icanhazip.com on the back-end).

6.  You should see these:

"It Worked\!
You just used Docker Compose via ContinualIntegration.com"

You are now done.  (Remember that modifications to the index.html command will require you to use "docker-compose build" once again.  New containers may conflict on port 8080 if you do not change the docker-compose.yml file or stop the containers from running.)

The above directions were adapted (but mostly copied) from Tecadmin.net. The directions above were tested in February of 2022.

How Do You Get Jenkins Working in a Docker Container?

One of the following problems apply:

Problem scenario #1
You have no idea how to start Jenkins in a Docker container.  What should you do?

OR

Problem scenario #2
You have run some Docker commands to try to start deploy Jenkins in a container.  You get output like this:

[4213] [10236] Disconnected
[9146] Connection from [::1]:41118
[9146] Extended attributes (16 bytes) exist <host=localhost>
[9146] Request upload-pack for '/repo'
[4213] [10255] Disconnected

How do you get Jenkins running in a Docker container?

Solution
1.  Install Docker.  If you need assistance with this, see this posting.

2.  Start the Docker service (e.g., run "sudo service docker start")

3.  Run these two commands:

docker run -d -v /var/jenkins_home:/var/jenkins_home:z -p 8080:8080 -p 50000:50000 --name myjenkins jenkins/jenkins:lts

sudo chown 1000:1000 /var/jenkins_home

4.  Run this:  docker ps -a

5.  Look at the output of the above command.  Find the container ID that was just created with step #3.  Then run this command (but substitute abcd1234 with the container ID you just identified):

docker start abcd1234

6.  Docker should now be accessible via the Docker host's external IP address on port 8080.  You can run this on the host to find the external IP address: curl icanhazip.com

In a web browser you should be able to go to x.x.x.x:8080 (where x.x.x.x is the external IP address of the server returned in from the curl command above) and get to the Jenkins instance in the Docker container.

You may want to see this posting for your initial set up because it explains how to enter a Docker container if you are new to Docker.

How Do You Delete Servers in AWS with Python?

Problem scenario
You want to write a Python program to delete servers.  How do you delete EC-2 instances in AWS with Python?

Solution
Prerequisites

a.  You have installed Boto3.  If you do not know how, see this posting. 
b.  You know the instance IDs.  If you do not know them, see this posting.

Procedures
Read the "Usage instructions" of this Python program we call "deleteec2.py". The content of this Python script is below.

""" Usage instructions
  1. replace "aaa111" with the aws_access_key_id of your account
  2. replace "bbb222" with the aws_secret_access_key of your account
     If you are not sure how to find these credentials do the following:
     To find the AWS Access Key ID and AWS Secret Access Key, in the AWS console, click on your name in the upper right hand corner.
     Then click on "My Security Credentials."  Click "Create New Access Key"  Click "Show Access Key."
  3.  Replace us-west-1 with the region that you want to list EC-2 instances for.
  4.  Replace i-1234abcd with the instance ID of the server you want to delete.  If you have multiple servers, place the instance IDs in single quotes and separate those quoted strings by commas inside the square brackets.
  5.  To run it, call it deleteec2.py and run it with a command like this: "python deleteec2.py"

"""

import boto3

ec2 = boto3.resource('ec2', aws_access_key_id=' aaa111', aws_secret_access_key=' bbb222', region_name='us-west-1')

alist = ['i-1234abcd']  # alist = ['i-1234abcd','i-5678-efgh'] is how multiple servers are deleted
ec2.instances.filter(InstanceIds=alist).stop()
ec2.instances.filter(InstanceIds=alist).terminate()