Showing posts with label S3. Show all posts
Showing posts with label S3. Show all posts

Wednesday, June 10, 2020

Deploy your first Kubernetes Service

We have setup our own Kubernetes cluster and we have installed the Kubernetes Dashboard. Let us try and install a service.

Nope, we are not going to do Hello World - I am bored with it

I created a small flask application which allows me to Browse S3 Buckets based on permission in IAM roles.

We will split this into two parts 
  1. Create a docker container and have this app running
  2. Create the same as a service in Kubernetes
Part 1 - Create a docker container and have an (Python Flask) app running inside the container 

Prerequisite:
  • Have Python Flask app which is running 
  • Install Docker
Steps to create the docker container
  • Create a folder for the app
    mkdir s3browser
  • Create the requirements file requirements.txt
    • List all the packages you need along with the versions
      Flask==1.1.2
      boto3==1.13.6
      werkzeug==0.16.1
      tzlocal==2.1
  • Create the Dockerfile
    • Choose a base image - Python:3.8.2
    • Specify the port for the container - 5000
    • Create the folder structure required in the container
    • Copy the files required from the local folder to the container
    • Specify the entry point - python
    • Specify the command to run - main.py
      FROM python:3.8.2
      WORKDIR /usr/src/app
      COPY requirements.txt ./
      RUN pip install -r requirements.txt
      RUN mkdir bootstrap fonts download upload
      COPY . .
      COPY ./bootstrap ./bootstrap
      COPY ./fonts ./fonts
      ENTRYPOINT ["python3"]
      CMD ["main.py"]
We now have all the required steps to create the docker image
[ec2-user@ip-10-0-1-38 app]$ sudo docker build -t s3browser .
Sending build context to Docker daemon  500.7kB
Step 1/10 : FROM python:3.8.2
3.8.2: Pulling from library/python
90fe46dd8199: Pull complete
35a4f1977689: Pull complete
bbc37f14aded: Pull complete
74e27dc593d4: Pull complete
4352dcff7819: Pull complete
deb569b08de6: Pull complete
98fd06fa8c53: Pull complete
7b9cc4fdefe6: Pull complete
512732f32795: Pull complete
Digest: sha256:8c98602bf4f4b2f9b6bd8def396d5149821c59f8a69e74aea1b5207713a70381
Status: Downloaded newer image for python:3.8.2
 ---> 4f7cd4269fa9
Step 2/10 : WORKDIR /usr/src/app
 ---> Running in 5d9cb6ae01f2
Removing intermediate container 5d9cb6ae01f2
 ---> 3e9513288f2c
Step 3/10 : COPY requirements.txt ./
 ---> 75b3d1cdab8d
Step 4/10 : RUN pip install -r requirements.txt
 ---> Running in 45827297fb12
Collecting Flask==1.1.2
  Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting boto3==1.13.6
  Downloading boto3-1.13.6-py2.py3-none-any.whl (128 kB)
Collecting werkzeug==0.16.1
  Downloading Werkzeug-0.16.1-py2.py3-none-any.whl (327 kB)
Collecting tzlocal==2.1
  Downloading tzlocal-2.1-py2.py3-none-any.whl (16 kB)
Collecting click>=5.1
  Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting itsdangerous>=0.24
  Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting Jinja2>=2.10.1
  Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting s3transfer<0 .4.0="">=0.3.0
  Downloading s3transfer-0.3.3-py2.py3-none-any.whl (69 kB)
Collecting jmespath<1 .0.0="">=0.7.1
  Downloading jmespath-0.10.0-py2.py3-none-any.whl (24 kB)
Collecting botocore<1 .17.0="">=1.16.6
  Downloading botocore-1.16.19-py2.py3-none-any.whl (6.2 MB)
Collecting pytz
  Downloading pytz-2020.1-py2.py3-none-any.whl (510 kB)
Collecting MarkupSafe>=0.23
  Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB)
Collecting python-dateutil<3 .0.0="">=2.1
  Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
Collecting docutils<0 .16="">=0.10
  Downloading docutils-0.15.2-py3-none-any.whl (547 kB)
Collecting urllib3<1 .26="">=1.20; python_version != "3.4"
  Downloading urllib3-1.25.9-py2.py3-none-any.whl (126 kB)
Collecting six>=1.5
  Downloading six-1.15.0-py2.py3-none-any.whl (10 kB)
Installing collected packages: werkzeug, click, itsdangerous, MarkupSafe, Jinja2, Flask, six, python-dateutil, docutils, jmespath, urllib3, botocore, s3transfer, boto3, pytz, tzlocal
Successfully installed Flask-1.1.2 Jinja2-2.11.2 MarkupSafe-1.1.1 boto3-1.13.6 botocore-1.16.19 click-7.1.2 docutils-0.15.2 itsdangerous-1.1.0 jmespath-0.10.0 python-dateutil-2.8.1 pytz-2020.1 s3transfer-0.3.3 six-1.15.0 tzlocal-2.1 urllib3-1.25.9 werkzeug-0.16.1
WARNING: You are using pip version 20.1; however, version 20.1.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 45827297fb12
 ---> ac86d48f81e6
Step 5/10 : RUN mkdir bootstrap fonts download upload
 ---> Running in 6fc0e64800a9
Removing intermediate container 6fc0e64800a9
 ---> e5b6c2505c07
Step 6/10 : COPY . .
 ---> 62002b4eefe0
Step 7/10 : COPY ./bootstrap ./bootstrap
 ---> 8909f349d50f
Step 8/10 : COPY ./fonts ./fonts
 ---> 1be3dd0c5262
Step 9/10 : ENTRYPOINT ["python3"]
 ---> Running in bf9e16f104bb
Removing intermediate container bf9e16f104bb
 ---> 4afaaef6b481
Step 10/10 : CMD ["main.py"]
 ---> Running in a5b3ecd0e25d
Removing intermediate container a5b3ecd0e25d
 ---> b63b9f6788b2
Successfully built b63b9f6788b2
Successfully tagged s3browser:latest
Run the docker image we have created
[ec2-user@ip-10-0-1-38 app]$ sudo docker run -d -p 5000:5000 s3browser
4a78858638e5c05e5c5352752ba04e16dbb7914f63ea38f77092060e117ff5b2
[ec2-user@ip-10-0-1-38 app]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
4a78858638e5        s3browser           "python3 main.py"   18 seconds ago      Up 17 seconds       0.0.0.0:5000->5000/tcp   nostalgic_kalam
Open the app in your browser



Part 2 - Host this service in your Kubernetes Cluster

Steps to host service:
  • Create your free docker account - hub.docker.com - user gavihs
  • Create your repository (make it a public repository) - s3browser
  • Tag your image as <Account>/<Repository> - gavihs/s3browser
    [ec2-user@ip-10-0-1-38 app]$ sudo docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    s3browser           latest              6a56635d563d        20 minutes ago      1.01GB
    python              3.8.2               4f7cd4269fa9        4 weeks ago         934MB
    [ec2-user@ip-10-0-1-38 app]$ sudo docker tag 6a56635d563d gavihs/s3browser
    [ec2-user@ip-10-0-1-38 app]$ sudo docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    gavihs/s3browser    latest              6a56635d563d        21 minutes ago      1.01GB
    s3browser           latest              6a56635d563d        21 minutes ago      1.01GB
    python              3.8.2               4f7cd4269fa9        4 weeks ago         934MB
    
  • Push docker image to docker repository
    [ec2-user@ip-10-0-1-38 app]$ sudo docker login -u gavihs
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    [ec2-user@ip-10-0-1-38 app]$ sudo docker push gavihs/s3browser
    The push refers to repository [docker.io/gavihs/s3browser]
    36e19271ecd9: Pushed
    a925ec3c1db0: Pushed
    15cd094801a0: Pushed
    9307954483b2: Pushed
    20ae7d89eead: Pushed
    d77ded6c9229: Pushed
    dd64728994ac: Pushed
    508c3f3b7a64: Pushed
    7e453511681f: Pushed
    b544d7bb9107: Pushed
    baf481fca4b7: Pushed
    3d3e92e98337: Pushed
    8967306e673e: Pushed
    9794a3b3ed45: Pushed
    5f77a51ade6a: Pushed
    e40d297cf5f8: Pushed
    latest: digest: sha256:9c579687302b0ba1683b263f9b1fab07080231d598325019c1f0afbf7a2031fb size: 3678
  • Create the deployment file - s3browser-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: s3browser
    spec:
      selector:
        matchLabels:
          run: s3browser
      replicas: 1
      template:
        metadata:
          labels:
            run: s3browser
        spec:
          containers:
          - name: s3browser
            image: gavihs/s3browser:latest
            ports:
            - containerPort: 5000
  • Create the deployment
    ubuntu@ip-10-0-1-79:~/flask-app$ kubectl create -f s3browser-deployment.yaml
    deployment.apps/s3browser created
  • Create the service
    ubuntu@ip-10-0-1-79:~/flask-app$ kubectl expose deployment.apps/s3browser
    service/s3browser exposed
    ubuntu@ip-10-0-1-79:~/flask-app$ kubectl get service
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes   ClusterIP   100.64.0.1              443/TCP    9h
    s3browser    ClusterIP   100.67.84.177           5000/TCP   4s
  • Access the service from kubernetes
    https://api-k8-shivag-io-covt8s-1234567890.eu-west-1.elb.amazonaws.com//api/v1/namespaces/default/services/https:s3browser:/proxy/browse?folder=





Friday, May 29, 2020

S3Browser

S3 Browser is a small python flask app. Normal S3 browser utilities available on the web require you to create a AccessKey & SecretID or an User Id. This creates a potential security breach.

This utility relies on IAM role assigned to the AWS resource where this is running. 

Features available:

  • Browse a bucket
  • Upload files into a folder
  • Download files from bucker/folder