Mega Menu

Tuesday, April 21, 2020

Docker Engine

Docker Engine comprises of three components -
   
        Docker Daemon - background process that manages docker object such as network, storage, containers, volumes.

        REST API - API interface that can provide instructions to Docker Daemon.

        Docker CLI - Command line interface that can provide instructions to Docker Daemon.


              


It is not always mandatory to have Docker CLI on the same machine of th Docker Engine. Below is an example of remote Docker Engine -


              


Command to use remote Docker Engine :

        docker -H={remote-docker-engine-host}:{port}











Docker Compose

Steps:
  • Install docker compose
  • Create docker-compose YAML file
  • Execute docker compose

docker-compose.yml

     redis:
       image: redis
       webapp:
         image: mywebapp
         ports:
           - 5000:80
         links:
           - redis 


Script:

     docker-compose up

                        container names will be prefixed with the directory name from which this script is being executed.


Docker - Command and Entrypoint

If a process inside the container is dead, the container exits and will no longer be running. 

Command is a process that is specified in the DockerFile, which should be executed when a Docker image is run.
The arguments will have to be hard-coded within the Dockerfile.

Docker File:

    FROM ALPINE

    CMD ["sleep","10"]    OR     
    CMD sleep 10
   
Docker Run:   

    docker run alpine
            This will execute
                    docker run alpine sleep 10
               
Entry point is the command that executes at the start of the container. The argument passed as input while running the container will be passed as input to the entry point command.
This will allow the command arguments to be dynamic, rather than hard-coded in the DockerFile
       
Docker File:

    FROM ALPINE

    ENTRYPOINT ["sleep"]
   
Docker Run:   

    docker run alpine 15
            This will execute
                    docker run alpine sleep 15
               
               
To set a default value to an EntryPoint command,

Docker File:

    FROM ALPINE

    ENTRYPOINT ["sleep"]

    CMD ["5"]   

   
Docker Run:   

    docker run alpine
            This will execute
                    docker run alpine sleep 5
               
    docker run alpine 20
            This will execute
                    docker run alpine sleep 20


To override the entrypoint command runtime, pass an entrypoint argument while running a docker container -

Eg:
         docker run --entrypoint sleep2 alpine 10   
                ----- this executes sleep2 process instead of sleep which is in the dockerfile


Docker Environment Variables


Find all available environment variables
    
         docker inspect {imageName}
   

Set environment variables while running the image

           docker run -e {ENV_VAR_NAME}={VALUE} {IMAGE_NAME}

Docker - Build and publish custom image to repository

Key Steps Involved -
  • Create a DockerFile
  • Build docker image with appropriate tag
    • docker build . -t rajesh.sripathi/test-web-app
  • Login to docker hub
    • docker login
  • Push the Image
    • docker push test-web-app

By default the image gets pushed to a public repository. To push it to private repository,
    •     Login to the hub, and create the repository first, and mark it as private. Then when you push to that repo, it will be private.

Docker Port Mapping Basic Scenario

Port mapping can be used to map a port on localhost with that of the port of docker container on which the application is running. Below RUN command can be used for that

             docker run -p 8001:8080 -p 50001:50000 jenkins
                                            where 8001 and 50001 are the localhost ports and 8080, 50000 are ports of docker image.


Running a Jenkins Container -

   docker run jenkins
        Once the download is complete, we should be able to access Jenkins through browser. To do this, you need to find the port of the jenkins image using 'ps' and ip using 'inspect'
   
          docker ps       
   

    docker inspect {containerId}
   
This can be simplified using the port mapping.
   
   
Detailed steps for using Jenkins Image     -     https://hub.docker.com/_/jenkins/

Sunday, April 19, 2020

OAuth and OpenId Connect (OIDC)

After few days of confusion around this topic, I finally decided to put together my understanding about Oauth2 and OpenId Connect. This may help give you a basic understanding and overview of the basic terminology and flow.

Thanks to Nate Barbettini for his wonderful sessions on Oauth and OIDC. One sample url below -
    https://www.youtube.com/watch?v=996OiexHze0

**Some of the diagrams in this document are from Nate's video

To start with, would like to mention couple of key things around OAuth and OIDC.
  1. OAuth is an authorization protocol and not recommended to directly use for Authentication.
  2. OIDC / OpenId Connect is an identity layer around OAuth to support authentication flow

Typical OAuth2.0 Flows -
  •     Authorization Code Flow (Involves front-end and back-end)
  •     Implicit Flow (purely client side)
  •     Resource Owner Password Credentials
  •     Client Credentials (purely server-side)
Will try to elaborate on the Authorization Code Flow and Implicit Flows in the next sections.

OAuth2.0 Authorization Code Flow

Below is a simple example of OAuth2.0 authorization code flow, with all the bold lines indicating the front-end flow and the dotted lines indicating the back-end server side invocations.


    OAuth2 Authorization Flow

The flow also introduces some of the key terminology of OAuth protocol (Terminology in Blue and Bold). Flow Description -
  • Client, which is the an entry point to the flow (eg: web browser), initiates authorization call to an Authorization server.
  • As a part of Authorization request, a redirect uri (uri to be redirected after successful authorization, response type (whether the request is for a auth code or identify token, etc.) and scope of the data to be allowed with the authorization code are specified.
  • Authorization server verifies the customer and redirects to a consent window, prompting the Resource Owner (end user) to review and provide consent for the server/application being used (eg: Yelp in this example) to access the profile and contacts.
  • Once the resources owner provides the consent, the authorization server, redirects the request to the redirect uri/callback url with Authorization Code in response.
  • The callback url typically initiates a process on server, which can use the authorization code to exchange for the scoped data.
  • The server does exchange the Authorization code with the Authorization server to get the Access Token, which is required to query for the required data. This data exchange uses a secret key know to the back-end server and authorization server only so as to ensure the security of the application.
  • Using the access token provided by Authorization server, the back-end server, queries the Resource Server (which is the source of Resource Owner's data) for relevant data.

Samples based on Google Authorization Server.

Authorization Request -

     https://accounts.google.com/o/oauth2/v2/auth?
     scope=profile&
     access_type=offline&
     include_granted_scopes=true&
     response_type=code&
     state=state_parameter_passthrough_value&
     redirect_uri=https%3A//oauth2.example.com/code&
    client_id=client_id



Authorization Code Response -

           https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7


Exchange Request for Access Token -
   
    POST /token HTTP/1.1
        Host: oauth2.googleapis.com
        Content-Type: application/x-www-form-urlencoded
        code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
        client_id=your_client_id&
        client_secret=your_client_secret&
        redirect_uri=https%3A//oauth2.example.com/code&
        grant_type=authorization_code


Sample Token Response -

    {
     
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
     
"expires_in": 3920,
     
"token_type": "Bearer",
     
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
     
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
    }

Sample Request to Resource Server (Google Drive in this case) -
   
      GET /drive/v2/files HTTP/1.1
        Host: www.googleapis.com
        Authorization: Bearer access_token

Detailed integration steps for a range of programming languages here - https://developers.google.com/identity/protocols/oauth2/web-server