{"id":19307496,"url":"https://github.com/pa/kodekloud-assignment","last_synced_at":"2026-05-05T01:42:00.557Z","repository":{"id":202220868,"uuid":"499480519","full_name":"pa/kodekloud-assignment","owner":"pa","description":"kodekloud docker swarm cluster assignment","archived":false,"fork":false,"pushed_at":"2022-06-08T18:36:16.000Z","size":1796,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-24T02:50:24.124Z","etag":null,"topics":["apparmor-profile","dind","docker","docker-compose","docker-swarm-cluster","priviliged-conatiner"],"latest_commit_sha":null,"homepage":"https://www.loom.com/share/00a853072d9445279cb9c85213e48913","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-06-03T11:08:55.000Z","updated_at":"2022-06-12T07:34:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"c578d2fa-3a34-4aaa-afa5-840bd4a44d6a","html_url":"https://github.com/pa/kodekloud-assignment","commit_stats":null,"previous_names":["pa/kodekloud-assignment"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pa/kodekloud-assignment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pa%2Fkodekloud-assignment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pa%2Fkodekloud-assignment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pa%2Fkodekloud-assignment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pa%2Fkodekloud-assignment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pa","download_url":"https://codeload.github.com/pa/kodekloud-assignment/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pa%2Fkodekloud-assignment/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284566163,"owners_count":27027038,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-15T02:00:06.050Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apparmor-profile","dind","docker","docker-compose","docker-swarm-cluster","priviliged-conatiner"],"created_at":"2024-11-10T00:11:15.157Z","updated_at":"2025-11-15T13:54:40.974Z","avatar_url":"https://github.com/pa.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kodekloud-assignment\n\nThis repo contains solutions for two tasks,\n\n1. Deploy a docker swarm stack that would run a container with `privileged` mode. For more details check [here](task-one/README.md).\n\n2. Run a ubuntu based docker container which can inturn run docker inside `(docker in docker mode)`. For more details check [here](task-two/README.md).\n\n## Directory Structure\n\n```bash\n.\n├── README.md\n├── docker-compose.yml\n├── task-one\n│   ├── Dockerfile\n│   ├── README.md\n│   ├── arch_diagram.png\n│   ├── container-handler.sh\n│   └── docker-compose.yml\n└── task-two\n    ├── Dockerfile\n    ├── README.md\n    ├── apparmor-profiles\n    │   ├── audit-all-writes\n    │   └── deny-all-writes\n    ├── arch_diagram.png\n    ├── container-handler.sh\n    └── docker-compose.yml\n```\n\n- [docker-compose.yml](docker-compose.yml) - Used to deploy docker swarm stack with two services ([task-one](task-one) and [task-two](task-two)) in a docker swarm cluster.\n- [task-one](task-one)\n  - [Dockerfile](task-one/Dockerfile) - Copies [container-handler](task-one/container-handler.sh) script into the filesystem of the container and execute it within the container\n  - [README.md](task-one/README.md) - Contains instructions to build image and deploy docker swarm stack in swarm cluster\n  - [arch_diagram.png](task-one/arch_diagram.png) - Architecture diagram for task one docker swarm stack\n  - [container-handler.sh](task-one/container-handler.sh) - Creates two sibiling containers, one with  `priviliged` mode enabled. Also waits for `docker stack rm \u003cstack_name\u003e` signal and kills the sibiling when `SIGTERM` is received\n  - [docker-compose.yml](task-one/docker-compose.yml) - It has one service and uses an existing network to deploy `container-handler` container to bring up sibiling containers, one with  `priviliged` mode enabled\n- [task-two](task-two)\n  - [Dockerfile](task-two/Dockerfile) - Copies [apparmor profiles](task-two/apparmor-profiles/) and [container-handler](task-two/container-handler.sh) script into the filesystem of the container and execute the script within container\n  - [README.md](task-two/README.md) - Contains instructions to build image and deploy docker swarm stack in swarm cluster\n  - [apparmor-profiles](task-two/apparmor-profiles/)\n    - [audit-all-writes](task-two/apparmor-profiles/audit-all-writes) - This profile will audit all the writes `(i.e creating dirs/files)` happening within the container and logs it to the kernel log\n    - [deny-all-writes](task-two/apparmor-profiles/deny-all-writes) - This profile will deny all the writes `(i.e creating dirs/files)` happening within the container and logs it to the kernel log\n  - [arch_diagram.png](task-two/arch_diagram.png) - Architecture diagram for task two docker swarm stack\n  - [container-handler.sh](task-two/container-handler.sh) - Creates one sibiling upper containers with  `priviliged` mode, updates/installs apparmor packages, copies apparmor profiles to `/etc/apparmo.d/` in the upper container, creates two child inner containers with apparmor profiles applied. Also waits for `docker stack rm \u003cstack_name\u003e` signal and kills the sibiling upper container `(including child inner containers)` when `SIGTERM` is received\n  - [docker-compose.yml](task-two/docker-compose.yml) - It has one service and uses an existing network to deploy `container-handler` container to bring up sibiling upper container with  `priviliged` mode enabled and two child inner containers\n\n## Deploy [task-one](task-one) and [task-two](task-two) to Swarm Cluster\n\nIn this section, we will be deploying both the tasks [task-one](task-one) and [task-two](task-two) in swarm cluster using a single [docker-compose](docker-compose.yml) file. We can deploy this stack to any cloud platform or even a local machine (with docker installed). For this deployment I'm going to use AWS Cloud platform.\n\n### Pre-requisites\n\n#### Docker Images\n\n- Task one service image - You can either build image using [Dockerfile](task-one/Dockerfile) (_if you also want to use custom image name and tag, make sure to change the same in [docker-compose.yml](docker-compose.yml#L12)_) or you can use my docker image in [pramodhayyappan/kk-task-one-container-handler](https://hub.docker.com/repository/docker/pramodhayyappan/kk-task-one-container-handler) in dockerhub\n\n    ```bash\n    # To build image with custom name and tag. By default, it uses the latest tag\n    docker build -f task-one/Dockerfile task-one -t pramodhayyappan/kk-task-one-container-handler:\u003ctag name\u003e\n    ```\n\n- Task two service image - You can either build image using [Dockerfile](task-one/Dockerfile) (_if you also want to use custom image name, make sure to change the same image name in [docker-compose.yml](docker-compose.yml#L23)_) or you can use my docker image in [pramodhayyappan/kk-task-two-container-handler](https://hub.docker.com/repository/docker/pramodhayyappan/kk-task-two-container-handler) in dockerhub\n\n    ```bash\n    # To build image with custom name and tag. By default, it uses the latest tag\n    docker build -f task-two/Dockerfile task-two -t pramodhayyappan/kk-task-two-container-handler:\u003ctag name\u003e\n    ```\n\n#### Cloud Infra deployment\n\n- Assuming that you have already set up your AWS Credentials in your local machine, create a Security Group(SG) to allow communication between nodes and make note of the SG name\n\n    ```bash\n    aws ec2 create-security-group --group-name swarm-cluster-sg --description \"swarm cluster security group\" --vpc-id \u003cvpc-id\u003e\n    ```\n\n- Create ingress rules with the protocols and ports mentioned in the [offical doc](https://docs.docker.com/engine/swarm/swarm-tutorial/#open-protocols-and-ports-between-the-hosts)\n\n    ```bash\n    aws ec2 authorize-security-group-ingress --group-id \u003csg name from previous step\u003e --protocol tcp --port 22 --cidr \u003ccidr ip\u003e\n    aws ec2 authorize-security-group-ingress --group-id \u003csg name from previous step\u003e --protocol tcp --port 2377 --cidr \u003ccidr ip\u003e\n    aws ec2 authorize-security-group-ingress --group-id \u003csg name from previous step\u003e --protocol tcp --port 7946 --cidr \u003ccidr ip\u003e\n    aws ec2 authorize-security-group-ingress --group-id \u003csg name from previous step\u003e --protocol udp --port 7946 --cidr \u003ccidr ip\u003e\n    aws ec2 authorize-security-group-ingress --group-id \u003csg name from previous step\u003e --protocol udp --port 4789 --cidr \u003ccidr ip\u003e\n    ```\n\n- Create `user-data.sh` script file with below content\n\n    ```bash\n    #!/bin/bash\n    sudo apt-get update\n    sudo apt-get install \\\n        ca-certificates \\\n        curl \\\n        gnupg \\\n        lsb-release -y\n    sudo mkdir -p /etc/apt/keyrings\n    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\n    echo \\\n    \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \\\n    $(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list \u003e /dev/null\n    sudo apt-get update\n    sudo apt-get install docker-ce docker-ce-cli containerd.io  docker-compose-plugin git -y\n    sudo groupadd docker\n    sudo usermod -aG docker $USER\n    newgrp docker\n    ```\n\n- Create two EC2 instances for Docker Swarm cluster\n\n    ```bash\n    aws ec2 run-instances --image-id \u003cami-id\u003e --count 1 --instance-type t2.xlarge --key-name \u003ckey-pair-name\u003e --security-group-ids \u003csg name from first step\u003e --subnet-id \u003csubnet-id\u003e --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ManagerNode}]' --user-data file://user-data.sh\n\n    aws ec2 run-instances --image-id \u003cami-id\u003e --count 1 --instance-type t2.xlarge --key-name \u003ckey-pair-name\u003e --security-group-ids \u003csg name from first step\u003e --subnet-id \u003csubnet-id\u003e --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=WorkerNode1}]' --user-data file://user-data.sh\n    ```\n\n- The infrastructure for docker swarm cluster with docker installed is ready\n\n### Deploy docker stack\n\n#### Stack deployment\n\n- Create a swarm cluster by executing the below command in manager node\n\n    ```bash\n    docker swarm init --advertise-addr \u003cMANAGER-IP\u003e\n    ```\n\n- Join worker node to the cluster by using the output of the init command or use `join-token` to generate the join command. The command will look like\n\n    ```bash\n    docker swarm join-token worker\n    docker swarm join --token \u003ctoken\u003e \u003cip\u003e:\u003cport\u003e\n    ```\n\n- Clone this repo to the manager node\n\n    ```bash\n    git clone https://github.com/pa/kodekloud-assignment.git\n\n    cd kodekloud-assignment\n    ```\n\n- Deploy docker stack\n\n    ```bash\n    docker stack deploy --compose-file docker-compose.yml \u003cstack-name\u003e\n    ```\n\n- Some useful commands to list stack, services, container and inspect container\n\n    ```bash\n    # To list docker stacks\n    docker stack ls\n\n    # To list services deployed by stack\n    docker stack services \u003cstack-name\u003e\n\n    # To list docker containers\n    docker ps\n\n    # to inspect docker container\n    docker inspect \u003ccontainer id or name\u003e\n\n    # runs a new command on a running container\n    docker exec -it \u003ccontainer id or name\u003e \u003cbash or shell\u003e\n\n    # to remove a docker stack\n    docker stack rm \u003cstack-name\u003e\n    ```\n\n#### Demo\n\nDemonstration and Testing of docker stack deployment\n\n[![asciicast](https://asciinema.org/a/500320.svg)](https://asciinema.org/a/500320)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpa%2Fkodekloud-assignment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpa%2Fkodekloud-assignment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpa%2Fkodekloud-assignment/lists"}