• Using kube-proxy to access deployments

    When we create a service on k8 cluster, it is often initialized with type of ClusterIP.

    We can still access the service using kubectl proxy.

    kubectl proxy allows one to interact with the API without the need for a Bearer token.

    Assuming we have a service called guestbook, we can access it as below:

    kubectl proxy > /dev/null &
    
    KC_PROXY_PID = $!
    
    SERVICE_PREFIX=http://localhost:8001/api/v1/proxy
    
    GUESTBOOK_URL = $SERVICE_PREFIX/namespaces/default/services/guestbook
    
    kubernetes kubectl proxy
  • yum update Protected multilib versions

    During a recent yum update, it failed with multiple lines of

    Error: Protected multilib versions:
    
    iptables-1.4.21-24.el7.i686 != iptables-1.4.21-23.el7.x86_64
    
    ( more error lines like above )
    ....
    
    

    From above, what the above error means is that for that specific package, version “X” of an RPM is installed for architecture x86_64 while yum was also instructed to install version “Y” of that same rpm for architecture i686.

    Rather than resolving each depedency manually, I enabled the Workstation Optional RPMs repo to locate the missing rpms and the problem was resolved:

    sudo subscription-manager repos --enable=rhel-7-workstation-optional-rpms
    
    sudo yum clean-all
    
    sudo rm -rf /var/cache/clean
    
    sudo yum update
    

    Additional Resources

    RedHat support ticket

    Same Issue from HPE

    redhat linux
  • Resolving dep ensure conflicts

    Sometimes when collborating on a golang project, it is possible to get dependency conflicts after runningdep ensure.

    The following is an approach I take to resolve them:

    • Run dep ensure -v with verbose to debug the issue.

    • Delete the repo’s Gopkg.lock

    • Clear out the ~GOPATH/src/pkg directory

    • Re-run dep ensure -v

    golang dep
  • Using virtualenv in python

    When working with python, sometimes it is important to create isolated environments due to compatibility issues with the libs being used. Some examples that come to mind is the dependency of pyOpenSSL lib by certbot or setting up a deep learning environment.

    To install virtualenv:

    pip install virtualenv
    

    To create an isolated environment based on a specific python version:

    virtualenv -p /usr/bin/python2.7 <path to env>
    

    Without the -p option, virtualenv defaults to the current python version.

    To activate the virtualenv:

    source <path to env>/bin/activate
    

    You should see the name of the virtualenv in brackets to the left of the terminal. As an extra step, do python -v to check that the version is the one specified above.

    To exit the virtualenv and return to the terminal:

    deactivate
    

    Also install virtualenvwrapper as it provides some useful utility commands to list and create virtualenvs:

    pip install virtualenvwrapper
    

    To list all available virtualenvs, for example:

    lsvirtualenv
    

    Additional Resources

    virtualenv docs

    virtualenvwrapper docs

    python virtualenv
  • golang pointer receiver error

    Assuming we have an interface declaration in go as so:

    type Stringer interface {
      String() string
    }
    

    We can create a custom struct to implement the interface like so:

    type struct MyStruct{
      Value string
    }
    
    func (m *MyStruct) String() string {
      return m.Value
    }
    

    If we try to assign a type of MyStruct to the Stringer interface, we will receive an error of __ MyType does not implement Stringer (String method has pointer receiver)__

    mytype := MyStruct{Value: "test"}
    
    var s Stringer
    s = m // throws the error above
    

    This is because the interface is defined on pointer types of *MyType and not the types of MyType

    To fix the error we just need to use the pointer type:

    mytype := MyStruct{Value: "test"}
    
    var s Stringer
    s = &m // no errors
    
    go golang error
  • Vendoring private github repos using dep

    When using dep for vendoring dependencies in a go project, I came across the issue of pulling down a private github repo. dep ensure -v keeps reporting of an error with the repo.

    To overcome this, you can create a ~/.netrc with your credentials to access the private repo. For example, when using github, you first need to create an Personal Github Token within your Account Settings. Then create a ~/.netrc file with the following format:

    machine github.com
        login [GITHUB USERNAME]
        password [GITHUB TOKEN]
    

    This is also documented in the dep repo:

    Private git repos using github token

    go golang dep
  • Kubectl and KUBECONFIG

    While working on a kubernetes based project, I had to set the $KUBECONFIG env variable in order to access a private cluster.

    Later, I started minikube and ran kubectl config view. This resulted in all my kubectl calls to the private cluster failing.

    The reason is due to the way kubectl config behaves when it detects the $KUBECONFIG env variable. According to the docs:

    kubectl config -h
    
    Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
    
    The loading order follows these rules:
    
      1. If the --kubeconfig flag is set, then only that file is loaded.  The flag may only be set once
    and no merging takes place.
    
      2. If $KUBECONFIG environment variable is set, then it is used a list of paths (normal path
    delimitting rules for your system).  These paths are merged.  When a value is modified, it is
    modified in the file that defines the stanza.  When a value is created, it is created in the first
    file that exists.  If no files in the chain exist, then it creates the last file in the list.
    
      3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.

    As stated in point 2 above, since my $KUEBCONFIG is still present, when I started minikube, it merges the minikube settings into file pointed to by $KUBECONFIG, updating it by merging the contents of minikube, and sets minikube as the current context. Which is why all the kubectl calls are going to the minikube cluster only.

    As a note to self, I need to remember to

    unset $KUBECONFIG
    kubernetes kubectl
  • Redhat Subscription Renewal

    Recently I had to update my Redhat subscription.

    Afterwards, the subscription-manager application kept showing as “No valid subscriptions found”. This was caused by a mismatch between the type of RHEL system I was running and the actual subscription type itself.

    To ensure that one renews to the right subscription type, simply use the following:

    cat /etc/redhat-release
    redhat linux
  • Checking for open ports in go lang

    I had to create a periodic status check for an open port on a specific host for a service I was creating recently. The status check has to work for both the localhost in development and also on the remote host.

    Using the [net][net pkg] package in Go I was able to come up with the following snippet for testing the localhost port:

    package main
    
    import (
      "fmt"
      "net"
    )
    
    func main() {
      l, err := net.Listen("tcp", ":" + port)
      defer l.Close()
    
      if err != nil {
        // Log or report the error here
        fmt.Printf("Error: %s\n", err)
      }
    }

    We use [Listen][net pkg Listen] above as it works for localhost only.

    For testing the remote port, we can use [DialTimeout][net pkg DialTimeout] as it accepts a custom timeout parameter, which we can use to check for timeout errors:

    package main
    
    import (
      "fmt"
      "net"
      "time"
    )
    
    func main() {
      // host -> the remote host
      // timeoutSecs -> the timeout value
      conn, err := net.DialTimeout("tcp", host, time.Duration(timeoutSecs)*time.Second)
      defer conn.Close()
    
      if err, ok := err.(*net.OpError); ok && err.TimeOut() {
        fmt.Printf("Timeout error: %s\n", err)
        return
      }
    
      if err != nil {
        // Log or report the error here
        fmt.Printf("Error: %s\n", err)
        return
      }
    }

    Resources

    net pkg

    net pkg Listen

    net pkg DialTimeout

    golang network

subscribe via RSS