Результаты выполнения тестового задания следует опубликовать на GitHub или захостить на любой открытой платформе (например, Github Pages) и отправить на почту devopscloudcamp@cloud.ru. Также следует указать свои контактные данные для получения обратной связи.
- Add the
your private keyto the directory you need - Specify it in the
your_repo/ansible.cfgfile under theprivate_key_fileoption. - Set the
inventoryfile in theinventoryoption. - Run the command
ansible-playbook playbook.ymlin directoryyour_repo/playbook.
To fast check playbook i used Vagrant
Execute next commands:
cd ~/your_repo/playbook
vagrant upAfter starting the virtual machine, you will see the execution of the playbook with the keys that vagrant creates for his needs. You should see next output
PLAY RECAP *********************************************************************
tag_cloud : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0After this you can check idempotence:
vagrant provision tag_cloudexpected result:
PLAY RECAP *********************************************************************
tag_cloud : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0You also can use inventory from vagrant inventory file in directory your_repo/playbook/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory to set up your ansible.cfg and test ansible-playbook playbook.yml command
However, for optimal idempotency testing, it's advisable to use specialized tools like Molecule.
- A Python script has been created using
Fastapito assign endpoints. - Created endpoints:
/id/hostname/authorreadinessliveness - A dependency file
requirements.txthas been created for launching applications
setup dependecies
cd ~/your_repo/app
pip install --upgrade -r requirements.txtAfter launch your app
AUTHOR=some_name UUID=some_valid_uuid_v4_or_not_valid_to_check_readiness_probe uvicorn main:app --host 0.0.0.0 --port 8000 --reloadcurl http://localhost:8000/created_endpointsA Dockerfile was created in the your_repo/app directory. To create it was used:
- Images are based on alpine.
- Specific versions of base images are pinned during the build.
- Dependencies in the
requirements.txtfile are pinned to specific versions required for the application's execution. - Multi-stage build is employed.
- Layers that are likely to change frequently, such as app source code, are positioned towards the end of the Dockerfile.
- The final image is created as
rootless.
I am aware of the existence of distroless images, https://github.com/GoogleContainerTools/distroless but the documentation separately states:
The following images are also published on gcr.io, but are considered experimental and not recommended for production usage:
gcr.io/distroless/python3-debian11
As a result, I chose not to utilize it.
I also chose not to set a default value for the environment variable UUID, because it's challenging for people to comprehend and remember entries like 54015250-c765-48a3-9921-6bc47bb40e11. If you happen to forget to specify this variable in a Kubernetes Deployment, your application will fail the readiness check. But if you have a default value set, this might go unnoticed.
To create the final image, run the following commands:
cd ~/your_repo/app
docker build -t your_hub_name/image_name:tag .
# If necessary, push to your custom Docker registry or Docker Hub
docker push your_hub_name/image_name:tagTo test your image, run the following commands:
# You can try different scenarios by passing a valid or invalid UUID to the variable.
docker run -e UUID=some_valid_or_not_UUID -d -p 8000:8000 your_hub_name/image_name:tag
curl http://localhost:8000/endpoints_in_app- A
deployment.ymlmanifest has been created, which sets up the namespacecloudruand the deployment itself. - A
service.ymlmanifest with a ClusterIP type has been created to serve the deployment.
The deployment has 3 replicas. The UUID variable is assigned the value of meta.uid during the deployment rollout. This variable is used in the readiness probe within the application code. The AUTHOR variable is also used for the readiness probe validation, ensuring you didn't forget to set the variable in the Dockerfile.
If you don't have kubernetes cluster use minikube
minikube start --kubernetes-version=v1.26.3rollout your deployment
cd ~/your_repo/manifest
kubectl apply -f ./Check readiness your pods and your service
kubectl get pod -n your_namespace
kubectl get svc -n your_namespace
# or inspect events to catch errors
watch kubectl events -n your_namespace
# or inspect pod logs
kubectl logs pod_name -n your_namespace --watchCheck working your app
kubectl port-forward your_pod_name 8000:8000
# open new terminal
curl http://localhost:8000/endpointsIn the /helm directory, a chart has been created that sets up a deployment and a service for it, as well as a README.md file generated using the helm-docs utility.
cd ~/your_repo/helm
# Ensure your manifests are correctly generated
helm template .
# Deploy
helm upgrade --install your_release_name . --namespace your_namespace --create-namespace# Check created service name
kubectl get svc -n your_namespace
# Launch pod with curl and sh/bash/etc
kubectl run pod_name --image image_with_curl_and_sh -n your_namespace
k exec -it debug -n your_namespace -- sh
# within container check your app endpoints
curl http://service_name:8000/endpointsEndpoints such as /id /hostname can be checked several times in a row to ensure that your service is load balancing between different pods, and you can receive a different UUID and /hostname from each pod.