🚀 CI/CD এবং Production Deployment
সম্পূর্ণ বাংলা গাইড - Code থেকে Production পর্যন্ত সম্পূর্ণ যাত্রা
📑 বিষয়বস্তু
- অংশ ১: সমস্যা এবং সমাধান
- অংশ ২: Software Delivery Basics
- অংশ ৩: Testing এবং Pytest
- অংশ ৪: CI/CD Fundamentals
- অংশ ৫: Git, Branching এবং Pull Request
- অংশ ৬: Jenkins এবং Pipeline as Code
- অংশ ৭: Environment Configuration ও Secrets Management
- অংশ ৮: Docker এবং Containerization
- অংশ ৯: Kubernetes Deployment - Production Scale
- অংশ ১০: Networking, Reverse Proxy এবং Service Discovery
- অংশ ১১: Production Debugging এবং Monitoring
- অংশ ১২: Best Practices Checklist
- অংশ ১৩: উপসংহার
🤔 অংশ ১: সমস্যা এবং সমাধান
বাস্তব গল্প: তামিম এবং নবীন - Production Disaster
🎬 দৃশ্য ১: একটি Tech Company অফিস, সকাল ৯টা
নবীন: "তামিম ভাইয়া! 🎉 সুসংবাদ! আমি আমাদের নতুন Product API feature তৈরি করে
ফেলেছি!"
তামিম: "ওহ! বাহ! Test করেছ?"
নবীন: "অবশ্যই ভাইয়া! আমার laptop-এ একদম 100% perfect! 😎"
তামিম: "Unit test? Automated test?"
নবীন: "না ভাইয়া... আমি নিজেই test করেছি। Browser খুলে API hit করেছি, response আসছে।
আর কী test লাগবে?" 😌
তামিম: "Code review?"
নবীন: "আমি নিজেই code লিখেছি, নিজেই review করেছি। আমার code-কে আমি খুব ভালোভাবে
চিনি।" 😎
তামিম: "Staging environment-এ deploy করে test করেছ?"
নবীন: "ভাইয়া, staging আবার কী? আমার laptop-এই তো সব চলছে!" 😂
তামিম: "আচ্ছা... production-এ deploy করেছ?"
নবীন: "জি ভাইয়া! ইতিমধ্যে করে ফেলেছি।"
তামিম: "😐 ... কোথায় deploy করেছ?"
নবীন: "Production server-এ, real users, real data—সব real!" 😁
তামিম: "নবীন... তুমি কি আমাকে আজকে চাকরি ছাড়ার একটা কারণ খুঁজে দিতে চাচ্ছ?" 😭
🕛 দুপুর ১২টা — তিন ঘণ্টা পর...
🔴 ALERT: PRODUCTION SERVER DOWN!
🔴 API ERROR RATE: 87%
🔴 USERS: ANGRY
🔴 SLACK: EXPLODING
নবীন: "ভাইয়া! 😱 API কাজ করছে না!"
তামিম: "কখন থেকে?"
নবীন: "প্রায় ২০ মিনিট ধরে।"
তামিম: "Monitoring alert আসেনি? Notification? Automated test? Code review?
Staging?"
নবীন: "...না ভাইয়া। কোনোটাই না।" 🥲
তামিম: "তাহলে deploy করলে কীভাবে?"
নবীন: "ভাইয়া... আমি শুধু git push করেছি... তারপর server-এ গিয়ে
git pull দিয়েছি।" 😐
তামিম: "আমি একটু পানি খেয়ে আসি।" 😭
🧑💻 তামিম: "শোনো নবীন, তোমার একটা জিনিস বুঝতে হবে। তোমার laptop-এ কাজ করছে মানেই
production-এ কাজ করবে—এমন কোনো guarantee নেই।"
নবীন: "কিন্তু ভাইয়া, আমার laptop-এ তো একদম ঠিক ছিল!"
তামিম: "তোমার laptop-এ Python version একরকম হতে পারে, production-এ আরেক version।
Dependency আলাদা হতে পারে। Environment variable missing থাকতে পারে। Database configuration আলাদা
হতে পারে। এমনকি তোমার laptop-এ যে package install করা আছে, production server-এ সেটাও নাও থাকতে
পারে।"
নবীন: "তাহলে deploy করার আগে কী করা উচিত ছিল?"
তামিম: "এখানেই আসে CI/CD।"
নবীন: "CI/CD আবার নতুন কোনো programming language?" 🤨
তামিম: "না ভাই! 😂 CI/CD কোনো programming language না। এটা software delivery করার
একটি automated process। তুমি code লিখবে → Git-এ push করবে → automated test চলবে → code quality
check হবে → build হবে → দরকার হলে review হবে → staging-এ deploy হবে → সব ঠিক থাকলে production-এ
deploy হবে।"
নবীন: "মানে আমি শুধু code push করব, বাকিগুলো automatically হবে?" 😮
তামিম: "Exactly! এটাই automation-এর beauty। আর মনে রেখো—"
"It works on my machine" is NOT a deployment strategy! 😂
তামিম: "এবার ঠিক আছে। চলো, তোমাকে CI/CD pipeline শেখাই।"
নবীন: "জি ভাইয়া! তবে আগে production server-টা বাঁচাই!" 😭😂
কী ঘটেছিল?
সমস্যা ১: কোনো Automated Testing ছিল না
যদি প্রতিটি code push-এর পর automated tests চলত, তাহলে bug-টি development-এ ধরা পড়ত।
সমস্যা ২: Code Review Process ছিল না
যদি অন্য একজন developer code দেখত, সম্ভবত তারা সমস্যা ধরত।
সমস্যা ৩: Manual Deployment Process
কোনো standardized deployment procedure ছিল না। তাই inconsistency হয়েছে।
সমস্যা ৪: কোনো Monitoring System ছিল না
Production-এ crash হওয়া পর্যন্ত কেউ জানল না।
সমস্যা ৫: Environment Mismatch
নবীনের laptop এবং production server-এর environment ভিন্ন ছিল।
তাহলে সমাধান কী?
সমাধান হলো—একটি systematic, automated এবং reliable software delivery process তৈরি
করা।
এই process নিশ্চিত করবে যে:
✓ প্রতিটি নতুন code change automated test-এর মধ্য দিয়ে যাবে
✓ Code merge করার আগে proper code review হবে
✓ Build ও deployment একটি standardized এবং reproducible process অনুসরণ করবে
✓ Development, Staging এবং Production environment যতটা সম্ভব consistent থাকবে
✓ Production-এ কোনো সমস্যা হলে সঙ্গে সঙ্গে monitoring alert ও notification পাওয়া যাবে
✓ নতুন version deploy করার সময় deployment controlled এবং reliable হবে
✓ কোনো issue হলে দ্রুত এবং safely আগের stable version-এ rollback করা যাবে
এই পুরো process-টিকেই আমরা CI/CD Pipeline হিসেবে ব্যবহার করি।
সহজভাবে বললে—CI/CD হলো code থেকে production পর্যন্ত software delivery-কে automation,
testing, validation এবং monitoring-এর মাধ্যমে নিরাপদ ও repeatable করার একটি পদ্ধতি।
তাহলে CI/CD আসলে কী?
CI — Continuous Integration
Developer-রা যখন নতুন code লিখে Git repository-তে push বা merge করে, তখন CI process automatically
সেই code যাচাই করে।
সাধারণত এই ধাপে:
✓ Code build করা হয়
✓ Automated unit test চালানো হয়
✓ Linting ও code quality check করা হয়
✓ প্রয়োজনীয় validation চালানো হয়
✓ Test fail করলে developer-কে জানানো হয়
অর্থাৎ, CI-এর মূল লক্ষ্য হলো—নতুন code যেন existing application-এর functionality নষ্ট না
করে, তা দ্রুত যাচাই করা।
CD — Continuous Delivery / Continuous Deployment
CI-এর মাধ্যমে code সফলভাবে test ও validate হওয়ার পর সেই code-কে deployment-এর জন্য প্রস্তুত করা
হয়।
Continuous Delivery: Tested এবং validated code automatically deployment-এর জন্য
ready থাকে। Production-এ deploy করার জন্য সাধারণত একটি manual approval বা release decision থাকতে
পারে।
Continuous Deployment: Code সমস্ত automated checks pass করলে সেটি automatically
production-এ deploy হয়ে যেতে পারে—অতিরিক্ত manual approval ছাড়াই।
অর্থাৎ, Delivery এবং Deployment এক জিনিস নয়; Continuous
Deployment হলো Continuous Delivery-এর আরও automated form।
এক লাইনে CI/CD
Developer Code লিখে → Git-এ Push করে → Automated Test → Code Quality Check → Build →
Review/Approval → Staging → Production → Monitoring → দরকার হলে Rollback
এই পুরো workflow-কে automated, consistent এবং repeatable করার ব্যবস্থাই হলো
CI/CD Pipeline।
📚 অংশ ২: Software Delivery Basics
একটি Application কীভাবে Users-এর কাছে পৌঁছায়?
এটি একটি fundamental প্রশ্ন যা আমাদের বুঝতে হবে CI/CD বোঝার আগে। ছোট একটি web application বা
microservice থেকে শুরু করে বিশাল enterprise application পর্যন্ত, সবকিছুকে একটি common process
follow করতে হয়।
সবচেয়ে সহজ Software Delivery Flow
Developer writes code
↓
Code gets stored in version control (Git)
↓
Code is compiled/built
↓
Code is tested
↓
Code is packaged
↓
Package is deployed to server
↓
Application runs on server
↓
Users access the application
↓
Users provide feedback
↓
Cycle repeats for new features
প্রতিটি পর্যায় বিস্তারিত
১. Development — Code লেখা
এ পর্যায়ে যা ঘটে:
Developer তার own machine (laptop)-এ নতুন feature বা bug fix লেখে। এই সময় বিভিন্ন tool ব্যবহার
করা হয় যেমন IDE (VS Code, PyCharm ইত্যাদি), version control (Git), local testing environment
ইত্যাদি।
উদাহরণ Process:
১. Feature branch তৈরি করুন: git checkout -b feature/new-api-endpoint
২. নতুন code লিখুন
৩. Local testing করুন: pytest চালান
৪. সন্তুষ্ট হলে commit করুন: git commit -m "Add new API endpoint"
৫. Remote repository-তে push করুন: git push origin feature/new-api-endpoint
এই পর্যায়ে যা গুরুত্বপূর্ণ:
• Code clean এবং readable হতে হবে
• Local environment-এ সব test pass করতে হবে
• Version control-এ সবকিছু properly tracked থাকতে হবে
২. Version Control এবং Repository
Git-এর ভূমিকা:
আমাদের code-এ একটি সিস্টেম দরকার যা track করবে কে কী পরিবর্তন করেছে এবং কখন। এটাই Git-এর মূল
উদ্দেশ্য।
প্রতিটি Developer তাদের নিজস্ব Branch-এ কাজ করে:
main/master = Production-ready code
develop = Development branch
feature/user-auth = নতুন feature-এর জন্য branch
bugfix/login-issue = Bug fix-এর জন্য branch
এটি isolated development সম্ভব করে। কোনো developer-এর কাজ অন্য developer-এর
কাজকে ভেঙে দেয় না।
Repository Location: Centralized remote repository থাকে (GitHub, GitLab,
Bitbucket ইত্যাদিতে) যেখানে সবাই তাদের code push করে।
৩. Testing
Test কেন গুরুত্বপূর্ণ?
Code লেখার পর এটি কাজ করছে কিনা তা verify করার জন্য test প্রয়োজন। Manual testing inefficient এবং
unreliable। তাই Automated Testing ব্যবহার করা হয়।
Testing-এর ধরন:
Unit Testing: Individual function বা method test করা।
উদাহরণ: def add(a, b): return a + b function test করা — assert add(2, 3) ==
5
Integration Testing: একাধিক component একসাথে কাজ করছে কিনা test করা — যেমন
database query, API call, response processing সব একসাথে।
End-to-End Testing: পুরো application workflow test করা — যেমন user registration
থেকে login পর্যন্ত পুরো process।
Performance Testing: Application কতটা দ্রুত response দেয় তা test করা।
Security Testing: Application-এ security vulnerability আছে কিনা তা check করা।
৪. Build
Build মানে কী?
Source code এক জায়গায় রাখলেই যথেষ্ট নয়। এটিকে একটি runnable format-এ convert করতে হয়। এই
process-কে build বলা হয়।
Python-এর ক্ষেত্রে: Python interpreted language, তাই compile করার প্রয়োজন নেই।
কিন্তু dependencies install এবং package করার প্রয়োজন হয়।
Java-এর ক্ষেত্রে: javac দিয়ে compile করতে হয় (.java →
.class), তারপর .class file-গুলো একটি JAR বা WAR file-এ package করতে হয়।
Build Process-এ যা হয়:
১. Dependencies সংগ্রহ করা (npm install, pip install ইত্যাদি)
২. Source code compile করা (যদি প্রয়োজন হয়)
৩. Code minify/optimize করা
৪. Assets (images, CSS, JS) bundle করা
৫. একটি executable বা runnable artifact তৈরি করা
৫. Packaging — Artifact তৈরি
Build artifact কী?
Build process থেকে যা বেরিয়ে আসে তাকে artifact বলা হয়। এটি হতে পারে JAR file (Java), WAR file
(Web Application), Docker Image, Executable binary, বা Wheel package (Python)।
Artifact-এর বৈশিষ্ট্য:
১. এটি self-contained — এর মধ্যে সব dependencies আছে
২. এটি reproducible — একই source থেকে build করলে একই artifact পাওয়া যায়
৩. এটি versionable — version number দিয়ে track করা যায়
৪. এটি distributable — একটি artifact-কে বিভিন্ন environment-এ deploy করা যায়
উদাহরণ: Docker image: myapp:1.2.3, JAR artifact:
myapp-1.2.3.jar, Python package: myapp-1.2.3.whl
৬. Deployment
Deployment মানে কী?
Artifact-কে একটি server-এ চালানো শুরু করাকে deployment বলা হয়।
Deployment Process:
১. Artifact-কে server-এ transfer করা
২. Server-এ dependencies install করা
৩. Configuration file setup করা
৪. Database migration চালানো (যদি প্রয়োজন হয়)
৫. Application start করা
৬. Health check করা (Application সঠিকভাবে running কিনা)
৭. Traffic শুরু করা
Deployment Strategies:
Big Bang Deployment: পুরো application একসাথে switch করা। Old version বন্ধ, নতুন
version চালু। ঝুঁকিপূর্ণ।
Rolling Deployment: Server-গুলোকে একটা একটা করে update করা। বাকি server-গুলো
running থাকে। কম downtime।
Blue-Green Deployment: দুটি identical environment রাখা। পুরোনো version
Blue-তে চলছে, নতুন version Green-এ deploy হয়। তারপর traffic switch করা হয়।
Canary Deployment: নতুন version শুধু কয়েকজন user-কে দেওয়া। বাকি user-রা old
version ব্যবহার করছে। সমস্যা না হলে ধীরে ধীরে সবাইকে দেওয়া হয়।
Production Environment কী?
Production হলো সেই Environment যেখানে real users আপনার application ব্যবহার করছে।
এটি নিয়ে বিশেষ যত্ন নিতে হয় কারণ এখানকার কোনো সমস্যা সরাসরি users-দের impact করে।
Production-এর বৈশিষ্ট্য:
১. High Availability — Application সবসময় running থাকতে হবে
২. Scalability — Traffic বাড়লে handle করতে পারতে হবে
৩. Security — বিশেষ নিরাপত্তা ব্যবস্থা থাকতে হবে
৪. Monitoring — সবসময় নজরদারি থাকতে হবে
৫. Backup ও Recovery — ডেটা backup এবং disaster recovery থাকতে হবে
৬. Performance Optimization — fast response time
Development এবং Production-এর পার্থক্য:
Development: Single machine, less security, fast iteration
Production: Multiple machines, high security, stability focus
🧪 অংশ ৩: Testing এবং Pytest
কেন Automated Testing এত গুরুত্বপূর্ণ?
একটি ছোট উদাহরণ:
ধরুন একটি simple function আছে যা দুটি সংখ্যা যোগ করে। এটি খুবই সহজ, তাই manual testing করা যায়।
একবার test করলাম, ঠিক আছে।
কিন্তু পরে যখন এই function-কে modify করা হলো (exponential যোগ করার জন্য), তখন ভুলবশত আগের
functionality ভেঙে গেল।
যদি automated test থাকত, তাহলে সেই test fail হতো এবং আমরা জানতে পারতাম কিছু ভুল আছে। কিন্তু
manual test-এ আমরা শুধু exponential functionality-ই test করেছিলাম, সাধারণ যোগটা test করিনি। ফলে
bug production-এ চলে গেল।
Automated Testing কীভাবে কাজ করে?
Automated testing মানে আপনি একবার লিখে রাখবেন কীভাবে test করতে হবে, তারপর সেটি বারবার নিজে নিজে
চলবে।
প্রথমে আমাদের একটি function আছে: def add(a, b): return a + b
এখন আমরা একটি test লিখি: def test_add(): assert add(2, 3) == 5
এই test-টি আমরা একবার লিখেছি। এখন যখনই আমাদের code change হবে, এই test automatically চলবে। যদি
add function-টি ভুলভাবে modify হয়, test fail হবে এবং আমরা জানতে পারব।
Pytest - Python Testing Framework
Pytest কী?
Pytest একটি জনপ্রিয় Python testing framework যা automated testing-কে সহজ করে দেয়। এটি test
discover করতে পারে, test run করতে পারে, এবং detailed report দিতে পারে।
Installation: pip install pytest
নিচে একটি simple test লেখা হলো, ফাইল: test_math.py
def add(a, b):
"""দুটি সংখ্যা যোগ করে।"""
return a + b
def subtract(a, b):
"""দুটি সংখ্যার পার্থক্য বের করে।"""
return a - b
# Test cases
def test_add_positive():
"""Positive সংখ্যা যোগের test।"""
assert add(2, 3) == 5
assert add(10, 20) == 30
assert add(0, 0) == 0
def test_add_negative():
"""Negative সংখ্যা যোগের test।"""
assert add(-5, -3) == -8
assert add(-10, 5) == -5
def test_subtract():
"""বিয়োগের test।"""
assert subtract(10, 3) == 7
assert subtract(5, 5) == 0
এই test-গুলো run করতে: pytest test_math.py
Output:
test_math.py::test_add_positive PASSED
test_math.py::test_add_negative PASSED
test_math.py::test_subtract PASSED
======= 3 passed in 0.05s =======
যদি কোনো test fail হয়:
test_math.py::test_add_positive FAILED
AssertionError: assert 6 == 5
এটি বলছে আমরা add(2, 3)-এ 6 পেয়েছি কিন্তু আশা করেছিলাম 5।
Real-World API Testing-এর উদাহরণ
একটি সাধারণ API থাকে যা Products return করে: GET /api/products
আমরা এর জন্য test লিখতে পারি:
import pytest
import requests
@pytest.fixture
def api_url():
"""Test-এর জন্য API URL।"""
return "http://localhost:5000"
def test_get_products_success(api_url):
"""Products endpoint ঠিকভাবে কাজ করছে কিনা।"""
response = requests.get(f"{api_url}/api/products")
# Status code check
assert response.status_code == 200
# Response format check
data = response.json()
assert isinstance(data, list)
assert len(data) > 0
# Product structure check
product = data[0]
assert "id" in product
assert "name" in product
assert "price" in product
def test_get_product_by_id(api_url):
"""একটি নির্দিষ্ট product fetch করা।"""
response = requests.get(f"{api_url}/api/products/1")
assert response.status_code == 200
product = response.json()
assert product["id"] == 1
def test_create_product(api_url):
"""নতুন product তৈরি করা।"""
new_product = {"name": "New Product", "price": 100}
response = requests.post(f"{api_url}/api/products", json=new_product)
assert response.status_code == 201
created_product = response.json()
assert created_product["name"] == "New Product"
assert created_product["price"] == 100
def test_delete_product(api_url):
"""Product delete করা।"""
response = requests.delete(f"{api_url}/api/products/1")
assert response.status_code == 204
def test_product_not_found(api_url):
"""Non-existent product fetch করা।"""
response = requests.get(f"{api_url}/api/products/99999")
assert response.status_code == 404
Test Coverage — আমরা কতটুকু test করেছি?
Code coverage measure করে code-এর কত অংশ tests দিয়ে cover হয়েছে।
Coverage বিভিন্ন level-এ হতে পারে:
• 50% coverage: Code-এর অর্ধেক test হয়েছে
• 80% coverage: Code-এর ৮০% test হয়েছে
• 100% coverage: সব code test হয়েছে
কিন্তু গুরুত্বপূর্ণ: 100% coverage মানে সব code test হয়েছে, কিন্তু সব edge case
cover হয়েছে তা নয়।
Coverage measure করতে:
pip install pytest-cov
pytest --cov=myapp test_myapp.py
এটি একটি report দেবে যা দেখাবে কোন ফাংশন বা ফাইল test হয়নি।
⚙️ অংশ ৪: CI/CD Fundamentals - সম্পূর্ণ ব্যাখ্যা
CI/CD আসলে কীভাবে কাজ করে?
একটি বাস্তব Scenario:
তামিম একটি নতুন feature develop করছে। সে তার own branch-এ কাজ করছে।
১. সে কাজ শেষ করলে code commit এবং push করে।
২. GitHub-এ একটি Pull Request খোলে।
৩. সাথে সাথে একটি webhook GitHub থেকে Jenkins server-এ signal পাঠায়।
৪. Jenkins automatic পুরো testing + build + deployment process শুরু করে।
৫. সব test pass হলে Jenkins GitHub-কে বলে "সব ঠিক আছে"।
৬. তামিম code review-র জন্য team-কে notify করে।
৭. অন্য developer code review করে approve করে।
৮. তামিম merge button চাপে।
৯. Jenkins আবার পুরো process চালায় এবং production-এ deploy করে।
সবকিছু automated এবং systematic।
Continuous Integration (CI) বিস্তারিত
CI-এর মূল উদ্দেশ্য: Developer-দের code একটি shared repository-তে merge করার পরও
Application সঠিকভাবে কাজ করে তা নিশ্চিত করা।
CI Process-এর ধাপ:
ধাপ ১: Code Push হয়
Developer code commit করে এবং repository-তে push করে। এই action-এর পর webhook trigger হয়।
ধাপ ২: CI Server জেগে ওঠে
Jenkins বা অন্য CI server webhook notification পায় এবং job শুরু করে।
ধাপ ৩: Repository Checkout
CI server latest code checkout করে: git clone repository
ধাপ ৪: Dependencies Install
সব প্রয়োজনীয় dependencies install করা হয়।
Python: pip install -r requirements.txt
Node.js: npm install
Java: Maven/Gradle দিয়ে download
ধাপ ৫: Code Quality Check
Linting এবং code style checking — Pylint/Flake8 (Python), ESLint (JavaScript), SonarQube
(general)।
ধাপ ৬: Unit Tests চলে
pytest বা অন্য testing framework সব test run করে।
ধাপ ৭: Integration Tests চলে
একাধিক component একসাথে কাজ করছে কিনা তা test করা।
ধাপ ৮: Security Scan
Dependency-তে কোনো known vulnerability আছে কিনা তা check করা — OWASP Dependency Check, Snyk-এর
মতো tool দিয়ে।
ধাপ ৯: Build
যদি সব test pass হয়, তাহলে build করা হয়।
ধাপ ১০: Result Report
সব ফলাফল GitHub-এ comment করা হয় যাতে developer জানে সবকিছু pass হয়েছে।
যদি কোনো ধাপ fail হয়: CI server সাথে সাথে job stop করে এবং developer-কে
notification দেয়। Merge করা যায় না।
Continuous Delivery (CD) বিস্তারিত
CD-এর মূল উদ্দেশ্য: যে code test pass করেছে এবং code review-এর মধ্য দিয়ে গেছে,
সেটিকে production-এ deploy করার জন্য প্রস্তুত করা।
CD Process-এর ধাপ:
ধাপ ১: Artifact তৈরি
Build থেকে যা বেরিয়ে আসে (Docker image, JAR file ইত্যাদি) তাকে artifact বলা হয়। এটিকে একটি
version number দিয়ে tag করা হয় — যেমন myapp:1.2.3
ধাপ ২: Artifact Publish করা
Artifact-কে একটি registry-তে push করা — Docker: Docker Registry-তে, Java: Artifactory/Nexus-এ,
Python: PyPI-তে।
ধাপ ৩: Staging Deployment
প্রথমে staging environment-এ deploy করা হয় (যা production-এর মতো কিন্তু real user-দের জন্য নয়)।
ধাপ ৪: Staging Tests
Staging environment-এ smoke test চালানো — health check, API endpoint test, integration test।
ধাপ ৫: Manual Approval (Optional)
কেউ manually approve করতে পারে production deployment-এর আগে।
ধাপ ৬: Production Deployment
Artifact production environment-এ deploy করা।
ধাপ ৭: Production Health Checks
Deployment-এর পরে application সঠিকভাবে running কিনা তা verify করা।
ধাপ ৮: Monitoring এবং Alerting
Production application-এর performance, error, এবং health continuously monitor করা।
Continuous Deployment বনাম Continuous Delivery
Continuous Delivery
Code production-এর জন্য ready থাকে, কিন্তু deploy করার জন্য human approval দরকার।
Manual deployment step থাকে, যা সাধারণত একজন DevOps engineer করে।
Safer কিন্তু তুলনামূলক ধীর।
Continuous Deployment
Code automatically production-এ deploy হয়, কোনো human approval ছাড়াই।
সম্পূর্ণ automated process, কোনো manual step নেই।
দ্রুত, কিন্তু tests comprehensive না হলে ঝুঁকিপূর্ণ।
CI/CD Pipeline Visualization
Developer commits code
↓
git push origin feature-branch
↓
GitHub receives push
↓
Webhook triggers CI server
↓
========== CI PHASE ==========
CI job starts
├─ Checkout code
├─ Install dependencies
├─ Run linting/code quality checks
├─ Run unit tests
├─ Run integration tests
├─ Run security scans
└─ Build artifact
↓
All checks PASSED?
├─ YES → Continue
└─ NO → Send failure notification, Stop
↓
========== CD PHASE ==========
Create artifact (Docker image)
↓
Tag artifact with version number
↓
Push artifact to registry
↓
Deploy to staging environment
↓
Run smoke tests on staging
↓
Await manual approval (if needed)
↓
Deploy to production
↓
Run health checks
↓
Monitor and alert
↓
SUCCESS! Application live for users
CI/CD Pipeline Tools-এর উদাহরণ
বিভিন্ন stage-এর জন্য বিভিন্ন tool ব্যবহার করা হয়:
| Stage |
জনপ্রিয় Tools |
| Version Control |
Git, GitHub, GitLab, Bitbucket |
| CI/CD Orchestration |
Jenkins, GitLab CI, GitHub Actions, CircleCI |
| Testing |
Pytest, JUnit, Mocha, RSpec |
| Code Quality |
SonarQube, Pylint, ESLint, Checkstyle |
| Build Tools |
Maven, Gradle, Make, npm |
| Container Registry |
Docker Hub, AWS ECR, Google Artifact Registry |
| Deployment |
Kubernetes, Docker Swarm, ECS, Lambda |
| Monitoring |
Prometheus, Grafana, ELK Stack, Datadog |
🌿 অংশ ৫: Git, Branching এবং Pull Request
কেন Git দরকার?
তিনজন developer একসাথে একই project-এ কাজ করছে — তামিম, নবীন এবং রহিম।
Scenario 1 — Version Control ছাড়া:
সবাই একই folder-এ কাজ করছে। নবীন একটি feature নিয়ে কাজ করছে, তামিম একটি architecture improvement
করছে, রহিম documentation update করছে। কিন্তু তারা একই file modify করেছে! এখন কার version রাখবে?
আর তিন সপ্তাহ আগের code দরকার হলে, সেটা কীভাবে পাওয়া যাবে? Chaos! 😱
Scenario 2 — Git দিয়ে:
এখন প্রত্যেকে নিজস্ব branch তৈরি করে কাজ করছে —
নবীন: git checkout -b feature/new-api
তামিম: git checkout -b feature/architecture-refactor
রহিম: git checkout -b docs/update-readme
প্রত্যেকে isolated ভাবে কাজ করছে, একে অপরকে কোনো সমস্যায় ফেলছে না। কাজ শেষ হলে সবাই নিজস্ব
changes commit করে, Pull Request খোলে, এবং একে অপরের code review করে দেয়। Order! 🎯
Branching Strategy
প্রতিটি organization-এর একটি নির্দিষ্ট branching strategy থাকে। সবচেয়ে জনপ্রিয় হলো Git
Flow:
• main/master branch: Production-ready code। এখানে শুধু release-ready code
থাকে।
• develop branch: Development branch। নতুন feature এখানে merge হয়।
• feature/* branches: নতুন feature-এর জন্য — যেমন
feature/user-authentication
• bugfix/* branches: Bug fix-এর জন্য — যেমন bugfix/login-crash
• release/* branches: একটি release ready করার জন্য — যেমন
release/1.2.0
• hotfix/* branches: Production-এ urgent fix-এর জন্য — যেমন
hotfix/security-vulnerability
Branching Flow Diagram
main (v1.0.0)
│
├── develop
│ │
│ ├── feature/user-auth (Developer A)
│ │ commits: "Add login endpoint"
│ │ commits: "Add password hashing"
│ │ [Pull Request → Code Review → Merge]
│ │
│ ├── feature/payment (Developer B)
│ │ commits: "Add payment API"
│ │ [Pull Request → Code Review → Merge]
│ │
│ └── bugfix/search (Developer C)
│ commits: "Fix search algorithm"
│ [Pull Request → Code Review → Merge]
│
└── release/1.1.0
commits: "Version bump to 1.1.0"
[Final tests]
└── Merge to main + tag v1.1.0
Pull Request Workflow সম্পূর্ণ ব্যাখ্যা
Pull Request (PR) হলো একটি formal request যা বলে: "আমি develop branch-এ নতুন
changes merge করতে চাই। দয়া করে review করুন এবং approve করুন।"
PR-এর একটি সম্পূর্ণ lifecycle:
ধাপ ১: Branch তৈরি করা
git checkout -b feature/new-payment-gateway
ধাপ ২: কাজ করা এবং Commit করা
git add .
git commit -m "Add payment gateway integration"
ধাপ ৩: Remote-এ Push করা
git push origin feature/new-payment-gateway
ধাপ ৪: GitHub-এ Pull Request খোলা
GitHub-এ "Create Pull Request" বাটনে click করে PR খোলা হয়, যেখানে PR title ও description
(কী changes করা হয়েছে, related issue, testing done) লেখা হয়।
ধাপ ৫: Automated Checks চলে
এখানেই CI/CD pipeline কাজ করে — code checkout, tests, code quality check, build, এবং result
GitHub-এ report করা। সব pass হলে ✅ green checkmark, কোনোটা fail হলে ❌ red X দেখা যায়।
ধাপ ৬: Code Review
সব test pass করার পরে, একজন বা একাধিক senior developer PR review করে — code logic, security
issue, performance, code style, এবং test coverage যাচাই করে। প্রয়োজনে comment দেয় — যেমন
"এই query-তে SQL injection risk আছে, parameterized query ব্যবহার করো।"
ধাপ ৭: Developer পরিবর্তন করে
Developer review comment address করে নতুন commit push করে।
ধাপ ৮: Re-review ও Approve
Reviewer আবার changes দেখে, ঠিক থাকলে approve করে।
ধাপ ৯: Merge
Approve হলে "Merge" বাটনে click করে branch merge করা হয়।
ধাপ ১০: Branch Delete
Merge-এর পরে feature branch delete করা হয়।
ধাপ ১১: CI/CD Final Run
develop branch-এ merge হওয়ার পরে CI/CD pipeline আবার চলে; সব pass হলে artifact তৈরি হয় এবং
staging environment-এ deploy হয়।
🔧 অংশ ৬: Jenkins এবং Pipeline as Code
Jenkins কেন দরকার?
নবীন: "তামিম ভাইয়া, প্রতিবার manually test চালানো, build করা, deploy করা — এত ধাপ কে মনে
রাখবে?"
তামিম: "এটাই তো automation-এর কাজ! আমরা এই পুরো process একটি script-এ লিখে রাখব, আর Jenkins নামের
একটি tool সেটা প্রতিবার আমাদের হয়ে চালাবে।"
নবীন: "Jenkins আবার কী?"
তামিম: "Jenkins একটি automation server। এটি একটি event (যেমন কেউ code push করলে) দেখে, এবং সেই
event অনুযায়ী পূর্বনির্ধারিত ধাপগুলো (build, test, deploy) automatically চালায়।"
Jenkins কী?
Jenkins একটি ওপেন-সোর্স automation server, যা CI/CD pipeline চালানোর জন্য
ব্যবহৃত হয়। এটি GitHub/GitLab-এর মতো repository-র সাথে যুক্ত থাকে (webhook-এর মাধ্যমে), এবং
নির্দিষ্ট trigger (যেমন push, PR, বা schedule) অনুযায়ী pipeline চালু করে।
Jenkins-এর মূল ধারণাগুলো:
• Job/Pipeline: কী কী ধাপ চালানো হবে তার সংজ্ঞা
• Agent: যে machine/container-এ pipeline চলে
• Webhook: GitHub থেকে Jenkins-কে notify করার mechanism
• Plugin: Jenkins-এর কার্যকারিতা বাড়ানোর জন্য extension (Docker, Kubernetes,
Slack notification ইত্যাদির জন্য plugin আছে)
Pipeline as Code — Jenkinsfile
ইংরেজি term: Pipeline as Code
সহজ বাংলায়: CI/CD pipeline-এর প্রতিটি ধাপ Jenkins-এর UI দিয়ে click করে configure
না করে, একটি text file (Jenkinsfile)-এ কোড আকারে লেখা হয়, এবং সেই file-টি project-এর
সাথেই Git repository-তে সংরক্ষিত থাকে। এর ফলে pipeline configuration-ও code-এর মতো version
control-এ থাকে, review করা যায়, এবং history track করা যায়।
আমাদের product-api project-এর জন্য একটি বাস্তব Jenkinsfile উদাহরণ:
pipeline {
agent any
environment {
DOCKER_REGISTRY = "docker.io/mycompany"
APP_VERSION = "1.0.${BUILD_NUMBER}"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install Dependencies') {
steps {
sh 'pip install -r requirements.txt'
}
}
stage('Lint') {
steps {
sh 'flake8 app/'
}
}
stage('Test') {
steps {
sh 'pytest --cov=app tests/'
}
}
stage('Build Docker Image') {
steps {
sh 'docker build -t ${DOCKER_REGISTRY}/product-api:${APP_VERSION} .'
}
}
stage('Push Image') {
steps {
sh 'docker push ${DOCKER_REGISTRY}/product-api:${APP_VERSION}'
}
}
stage('Deploy to Staging') {
steps {
sh 'kubectl set image deployment/product-api-staging app=${DOCKER_REGISTRY}/product-api:${APP_VERSION}'
}
}
stage('Smoke Test on Staging') {
steps {
sh 'curl -f https://staging.example.com/health || exit 1'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
steps {
input message: 'Deploy to production?'
sh 'kubectl set image deployment/product-api app=${DOCKER_REGISTRY}/product-api:${APP_VERSION}'
}
}
}
post {
success {
echo "Pipeline সফলভাবে সম্পন্ন হয়েছে!"
}
failure {
echo "Pipeline fail করেছে। Rollback বিবেচনা করুন।"
}
}
}
Jenkinsfile-এর প্রতিটি অংশ বুঝি
agent any — এই pipeline যেকোনো available Jenkins agent-এ চলতে
পারবে।
environment { ... } — পুরো pipeline জুড়ে ব্যবহৃত environment
variable define করা হয়।
stages { stage('...') { steps { ... } } } — Pipeline কে ধাপে ধাপে
(stage) ভাগ করা হয়, প্রতিটি stage-এর ভেতরে নির্দিষ্ট কমান্ড (steps) থাকে।
when { branch 'main' } — এই stage শুধুমাত্র main
branch-এর জন্য চলবে, feature branch-এর জন্য না।
input message: '...' — এখানে pipeline থেমে manual approval-এর
অপেক্ষা করে, যা আগে আলোচিত Continuous Delivery-এর manual approval ধাপের বাস্তবায়ন।
post { success { ... } failure { ... } } — Pipeline শেষ হওয়ার পরে,
ফলাফল অনুযায়ী (success/failure) নির্দিষ্ট action চালানো হয় — যেমন team-কে notify করা।
লক্ষ্য করুন — এই Jenkinsfile-এর প্রতিটি ধাপ ঠিক অংশ ৪-এ আলোচিত CI/CD process-এর সাথে মিলে যায়:
Checkout → Test → Build → Staging → (Approval) → Production। Jenkins শুধু এই ধাপগুলোকে automate
করছে।
🔐 অংশ ৭: Environment Configuration ও Secrets Management
নবীনের Configuration সমস্যা
নবীন: "তামিম ভাইয়া, আমি Jenkins pipeline সেটআপ করেছি এবং Docker image ready। এখন কি deploy করতে
পারি?"
তামিম: "নবীন, আরও একটি গুরুত্বপূর্ণ জিনিস বাকি — Configuration। Development, Staging এবং
Production-এ আলাদা আলাদা configuration প্রয়োজন — আলাদা database URL, আলাদা API key।"
নবীন: "আমার তো একটা .env file আছে!"
তামিম: "ভালো শুরু। কিন্তু .env file-এ যদি production-এর secret (database password,
API key) থাকে, আর সেটা যদি ভুলবশত Git-এ commit হয়ে যায়, তাহলে সেটা একটি বড় security ঝুঁকি হয়ে
দাঁড়ায়। তাই config আর secret আলাদাভাবে, নিরাপদে manage করতে হয়।"
Configuration বনাম Secrets
Configuration
সাধারণ, non-sensitive সেটিং — যেমন log level, feature flag, replica count।
Git-এ commit করা নিরাপদ। Kubernetes-এ ConfigMap হিসেবে রাখা হয়।
Secrets
Sensitive তথ্য — যেমন database password, API key, TLS certificate।
কখনো plain text-এ Git-এ commit করা উচিত না। Kubernetes-এ Secret হিসেবে বা
একটি dedicated secret manager-এ রাখা হয়।
Environment-ভিত্তিক Configuration (12-Factor App নীতি)
একটি সুপরিচিত নীতি হলো — application code-এর মধ্যে কোনো environment-নির্দিষ্ট মান (hardcoded
value) না রেখে, সেগুলো environment variable-এর মাধ্যমে সরবরাহ করা। এর ফলে একই Docker image
development, staging, এবং production — সব জায়গায় ব্যবহার করা যায়, শুধু environment variable
পাল্টে।
# .env.example — শুধু structure দেখানোর জন্য, আসল secret এখানে থাকে না
DATABASE_URL=postgresql://user:password@localhost:5432/product_dev
REDIS_URL=redis://localhost:6379
LOG_LEVEL=DEBUG
ENVIRONMENT=development
গুরুত্বপূর্ণ: .env file-এ আসল secret রাখা হলে, সেটি অবশ্যই
.gitignore-এ যুক্ত করতে হবে, যাতে ভুলবশত Git repository-তে commit না হয়ে যায়। শুধু
.env.example (placeholder value সহ) Git-এ রাখা উচিত।
Kubernetes-এ ConfigMap ও Secret
Kubernetes-এ non-sensitive configuration রাখা হয় ConfigMap-এ, আর sensitive তথ্য
রাখা হয় Secret-এ (যা base64-encoded থাকে — এটি encryption না, তাই cluster-level
access control এবং প্রয়োজনে external secret manager ব্যবহার করা গুরুত্বপূর্ণ)।
apiVersion: v1
kind: ConfigMap
metadata:
name: product-api-config
namespace: production
data:
LOG_LEVEL: "INFO"
ENVIRONMENT: "production"
FEATURE_CACHE_ENABLED: "true"
---
apiVersion: v1
kind: Secret
metadata:
name: product-api-secrets
namespace: production
type: Opaque
data:
# মান base64-encoded আকারে রাখা হয়
database-url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0Bwcm9kLWRiOjU0MzIvcHJvZHVjdA==
Deployment-এর ভেতরে এগুলো environment variable হিসেবে ব্যবহার করা যায়:
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: product-api-config
key: LOG_LEVEL
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: product-api-secrets
key: database-url
Jenkins-এ Secrets ব্যবহার
Jenkins-এ সরাসরি Jenkinsfile-এর মধ্যে password/API key লেখা হয় না। এর বদলে Jenkins-এর
Credentials feature ব্যবহার করা হয়, যেখানে secret একবার নিরাপদে সংরক্ষণ করে
রাখা যায়, এবং pipeline-এ শুধু একটি reference ID ব্যবহার করা হয়।
environment {
DOCKER_CREDENTIALS = credentials('docker-hub-credentials')
}
stages {
stage('Push Image') {
steps {
sh 'echo $DOCKER_CREDENTIALS_PSW | docker login -u $DOCKER_CREDENTIALS_USR --password-stdin'
sh 'docker push ${DOCKER_REGISTRY}/product-api:${APP_VERSION}'
}
}
}
Configuration Management Best Practices
১. Secrets আলাদা রাখুন
Database password, API key ইত্যাদি কখনো code-এ hardcode করবেন না — Kubernetes Secret বা একটি
dedicated secret manager ব্যবহার করুন।
২. Environment-specific config
প্রতিটি environment (dev, staging, prod)-এর জন্য আলাদা configuration রাখুন, কিন্তু একই code/image
ব্যবহার করুন।
৩. .gitignore ঠিকভাবে সেট করুন
.env-এর মতো secret-বহনকারী file যেন কখনো Git-এ commit না হয়।
৪. Configuration version control-এ রাখুন (secret ছাড়া)
ConfigMap-এর মতো non-sensitive config YAML file Git-এ রাখা যায়, review করা যায়।
৫. Access ও পরিবর্তনের audit trail রাখুন
কে কখন কোন secret access করেছে বা পরিবর্তন করেছে, তা track করা প্রোডাকশন সিস্টেমে গুরুত্বপূর্ণ।
🐳 অংশ ৮: Docker এবং Containerization
নবীনের Docker Nightmare
নবীন একটি Python application লিখেছে। Local machine-এ একদম perfect কাজ করছে।
নবীন: "তামিম ভাইয়া, এটা production-এ যাবে। কিন্তু আমি যদি production server-এ code সরাসরি push
করি, তাহলে environment issue হবে না?"
তামিম: "হবে নবীন, একশ বার হবে। তাই Docker ব্যবহার করব। Docker একটি container-এর মধ্যে আমাদের
application এবং সব dependency, পুরো environment সহ প্যাক করে রাখে।"
নবীন: "মানে Virtual Machine?"
তামিম: "না, VM-এর চেয়ে অনেক হালকা এবং দ্রুত। VM একটি সম্পূর্ণ OS চালায়। Docker শুধু application
চালায়, host-এর OS kernel share করে।"
Docker Architecture
Developer's Laptop
├─ Dockerfile
├─ app.py
├─ requirements.txt
└─ other files
↓
docker build -t myapp:1.0 .
↓
Docker Image (Artifact)
├─ Base OS layer (Ubuntu, Alpine, etc)
├─ Python layer
├─ Dependencies layer
├─ Application code layer
└─ Metadata
↓
Push to Docker Registry
├─ Docker Hub
├─ AWS ECR
└─ Google Artifact Registry
↓
Production Environment
├─ docker run myapp:1.0
├─ Container starts
└─ Application running
একটি Real-World Dockerfile (Multi-stage Build)
# Stage 1: Builder
FROM python:3.9-slim as builder
WORKDIR /build
# Build dependencies install করা
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
# Virtual environment তৈরি করা
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
# Stage 2: Runtime
FROM python:3.9-slim
WORKDIR /app
# Builder থেকে শুধু virtual environment কপি করা
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
COPY . .
# Security-এর জন্য non-root user তৈরি করা
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
USER appuser
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"]
Multi-stage build কেন? Stage 1 (builder)-এ compiler ও build tool ইনস্টল হয়,
যেগুলো final image-এ থাকার দরকার নেই। শুধু Stage 2-তে প্রয়োজনীয় virtual environment এবং code
কপি করা হয় — ফলে final image ছোট ও নিরাপদ হয়।
Docker Commands যা Development থেকে Production পর্যন্ত চলে
Development:
docker build -t product-api:dev .
docker run -p 8000:8000 product-api:dev
Testing:
docker run product-api:dev pytest
Production Build ও Push:
docker build -t product-api:1.2.3 .
docker tag product-api:1.2.3 docker.io/mycompany/product-api:1.2.3
docker push docker.io/mycompany/product-api:1.2.3
Production-এ Run:
docker pull docker.io/mycompany/product-api:1.2.3
docker run -d -p 8000:8000 --name product-api -e DATABASE_URL=... docker.io/mycompany/product-api:1.2.3
Docker Compose — একাধিক Service একসাথে
version: '3.8'
services:
app:
build: .
container_name: product_app
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/product
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
networks:
- app-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
db:
image: postgres:13-alpine
container_name: product_db
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=product
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
container_name: product_cache
volumes:
- redis_data:/data
networks:
- app-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
volumes:
postgres_data:
redis_data:
networks:
app-network:
driver: bridge
☸️ অংশ ৯: Kubernetes Deployment - Production Scale
নবীনের Scaling Problem
নবীনের product-api এখন viral হয়েছে। একদিনে ১০ লক্ষ request আসছে।
নবীন: "তামিম ভাইয়া, server crash হয়ে যাচ্ছে। একটা server তো এই লোড সামলাতে পারছে না।"
তামিম: "এখন আমাদের Kubernetes দরকার। Kubernetes তোমার container-গুলোকে একাধিক server-এ distribute
করে এবং load balance করে।"
নবীন: "কিন্তু আমি যদি ১০টি server-এ ১০টি container চালাই, তাহলে সেগুলো manually manage করব
কীভাবে?"
তামিম: "এটাই Kubernetes-এর কাজ। তুমি বলবে 'আমার ৫টি replica দরকার', Kubernetes নিজে নিজে ৫টি pod
চালু করবে। কোনো pod crash করলে এটি নতুন একটি চালু করবে। Traffic বাড়লে স্বয়ংক্রিয়ভাবে আরও pod
চালু করবে।"
Kubernetes Deployment উদাহরণ
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-api
namespace: production
labels:
app: product-api
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: product-api
template:
metadata:
labels:
app: product-api
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: docker.io/mycompany/product-api:1.2.3
ports:
- name: http
containerPort: 8000
envFrom:
- configMapRef:
name: product-api-config
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: product-api-secrets
key: database-url
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: product-api
namespace: production
spec:
type: ClusterIP
selector:
app: product-api
ports:
- name: http
port: 80
targetPort: 8000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: product-api-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: product-api
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Kubernetes-এর গুরুত্বপূর্ণ ধারণা
| ধারণা |
ব্যাখ্যা |
| Pod |
Kubernetes-এর সবচেয়ে ছোট deployable একক — এক বা একাধিক container একসাথে চলে |
| Deployment |
কতগুলো Pod replica চলবে এবং কীভাবে update হবে তা নিয়ন্ত্রণ করে |
| Service |
Pod-গুলোর জন্য একটি stable network endpoint সরবরাহ করে |
| Liveness Probe |
Container "বেঁচে" আছে কিনা যাচাই করে — fail করলে Kubernetes container restart করে |
| Readiness Probe |
Container traffic নেওয়ার জন্য প্রস্তুত কিনা যাচাই করে — fail করলে traffic পাঠানো বন্ধ হয় |
| HPA (Horizontal Pod Autoscaler) |
CPU/Memory ব্যবহারের উপর ভিত্তি করে Pod-এর সংখ্যা স্বয়ংক্রিয়ভাবে বাড়ায়/কমায় |
Kubernetes-এ কীভাবে Rolling Update হয়
নতুন version deploy করার সময়:
১. একটি নতুন pod চালু হয় (নতুন version-এর)
২. নতুন pod-এ readiness probe চলে
৩. যদি healthy হয়, traffic ধীরে ধীরে নতুন pod-এ যেতে শুরু করে
৪. পুরোনো pod-গুলো একটার পর একটা gracefully shutdown হয়
৫. এই প্রক্রিয়া সব pod update না হওয়া পর্যন্ত চলতে থাকে
উপযোগী Commands:
kubectl rollout status deployment/product-api
kubectl rollout history deployment/product-api
kubectl rollout undo deployment/product-api
kubectl set image deployment/product-api app=docker.io/mycompany/product-api:2.0.0
🔗 অংশ ১০: Networking, Reverse Proxy এবং Service Discovery
প্রথমে বুঝি: কেন সরাসরি Application Expose করা যায় না
নবীন তার Python application container-এ রেখেছে, port 8000-এ listen করছে।
তামিম: "এখন আমাদের একটি web server দরকার, যা HTTP/HTTPS request handle করবে, SSL certificate
manage করবে, এবং user-দের request সঠিকভাবে আমাদের application-এ forward করবে।"
নবীন: "আমরা কি সরাসরি port 8000 user-দের জন্য expose করতে পারি না?"
তামিম: "এটি একাধিক সমস্যা তৈরি করবে — Standard HTTP(80)/HTTPS(443) port ব্যবহার করা যাবে না, SSL
certificate manage করা কঠিন হবে, একাধিক application থাকলে port conflict হবে, এবং load balancing
করা কঠিন হবে। এর জন্য আমরা একটি Reverse Proxy ব্যবহার করি — যেমন Caddy।"
Caddy কী?
Caddy একটি modern web server এবং reverse proxy, যা automatic HTTPS support দেয়।
মূল বৈশিষ্ট্য:
✓ Automatic HTTPS: Let's Encrypt-এর মাধ্যমে স্বয়ংক্রিয় SSL certificate
✓ Easy Configuration: Caddyfile নামের সহজ configuration format
✓ Reverse Proxy: Request backend server-এ forward করে
✓ Load Balancing: একাধিক backend-এ traffic distribute করে
সহজভাবে: Caddy = Production-ready Web Server + Reverse Proxy + HTTPS Management
Caddy কীভাবে কাজ করে
Internet Users
↓
HTTPS (443)
↓
Caddy (Reverse Proxy)
├─ SSL/TLS Termination
├─ Request Routing
├─ Load Balancing
└─ Logging
↓
HTTP (8000)
↓
Python Application
↓
Response ফিরে যায় Caddy হয়ে User-এর কাছে
একটি Simple Caddyfile
# Caddyfile
api.example.com {
# Automatic HTTPS by default
reverse_proxy localhost:8000 {
header_up X-Forwarded-For {http.request.remote}
header_up X-Forwarded-Proto {http.request.proto}
}
log {
output file /var/log/caddy/access.log
format json
}
}
# HTTP কে HTTPS-এ redirect করা
example.com {
redir https://api.example.com{uri}
}
Docker Compose-এ Caddy
services:
app:
build: .
container_name: python_app
expose:
- "8000"
networks:
- app-network
caddy:
image: caddy:2-alpine
container_name: caddy_server
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
networks:
- app-network
depends_on:
- app
restart: unless-stopped
volumes:
caddy_data:
networks:
app-network:
driver: bridge
Caddy বনাম Nginx
Caddy
✓ Automatic HTTPS
✓ সহজ configuration
✓ Modern, Go-based
✗ Nginx-এর চেয়ে কম popular/battle-tested
Nginx
✓ অত্যন্ত দ্রুত ও lightweight
✓ ব্যাপকভাবে ব্যবহৃত ও পরীক্ষিত
✗ Configuration তুলনামূলক জটিল
✗ HTTPS setup manual (certbot ইত্যাদি লাগে)
Kubernetes-এ Service Discovery
নবীন ৩টি pod চালাচ্ছে — একটি request handle করছে, একটি database queries করছে, একটি cache handle
করছে।
নবীন: "তামিম ভাইয়া, এই pod-গুলো একে অপরের সাথে কীভাবে communicate করবে? IP address দিয়ে সরাসরি
না?"
তামিম: "Pod IP restart হলেই পরিবর্তিত হয়ে যায়, তাই সেটার উপর নির্ভর করা যায় না। আমরা Kubernetes
Service ব্যবহার করি — এটি একটি stable নাম/endpoint দেয়, যা সবসময় সঠিক pod-এর
কাছে request পৌঁছে দেয়।"
Service-এর ধরন
| Type |
ব্যবহার |
| ClusterIP (ডিফল্ট) |
শুধুমাত্র cluster-এর ভেতরে যোগাযোগের জন্য, বাইরে থেকে access নেই |
| NodePort |
প্রতিটি node-এ একটি নির্দিষ্ট port open করে বাইরে থেকে access দেয় |
| LoadBalancer |
Cloud provider-এর load balancer ব্যবহার করে বাইরে থেকে access দেয় |
| Ingress |
HTTP/HTTPS routing সহ advanced, domain/path-ভিত্তিক networking |
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: product-api-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: api-example-tls
rules:
- host: api.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: product-api
port:
number: 80
Service Discovery কীভাবে কাজ করে
Pod A (App)
↓
curl http://product-db:5432
↓
Kubernetes DNS lookup
↓
product-db.production.svc.cluster.local
↓
Service-এর stable IP (উদাহরণ: 10.0.1.50)
↓
Endpoints list lookup
Available Pods:
- 10.0.2.10:5432
- 10.0.2.11:5432
↓
Load balancer একটি Pod বেছে নেয়
↓
Connection established
🔍 অংশ ১১: Production Debugging এবং Monitoring
নবীনের রাত ৩টার Crisis Call
রাত ৩টা। নবীনের ফোন বেজে উঠল — একটি alert এসেছে।
Alert: "product-api pods CrashLoopBackOff status-এ আছে"
নবীন তামিম ভাইয়াকে call করে: "সিনিয়র, pod crash করছে। কীভাবে debug করব?"
তামিম: "প্রথমে শান্ত থাকো। Step by step যাই। প্রথমে pod-এর status দেখো।"
নবীন: kubectl get pods -n production
Output: product-api-xxxxx 0/1 CrashLoopBackOff 5 2m
তামিম: "এখন logs দেখো।"
নবীন: kubectl logs product-api-xxxxx -n production
Logs: Error: Connection refused: postgresql://product-db:5432
তামিম: "আহ, database connection সমস্যা। Postgres-এর Service আছে কি?"
নবীন: kubectl get svc -n production
Output: Database service missing!
তামিম: "এটাই সমস্যা। Database deployment ও তার Service ছাড়া app connect করতে পারবে না। Database
deployment redeploy করো।"
Production Debugging Checklist
Pod-এ সমস্যা?
kubectl get pods -n production
kubectl describe pod <pod-name> -n production
kubectl logs <pod-name> -n production
Service connect করছে না?
kubectl get svc -n production
kubectl get endpoints <service-name> -n production
Networking সমস্যা?
kubectl exec -it <pod> -- ping <service>
kubectl exec -it <pod> -- nslookup <service>
Resource limit সমস্যা?
kubectl top nodes
kubectl top pods -n production
Configuration সমস্যা?
kubectl get configmap -n production
kubectl get secrets -n production
kubectl describe configmap <name> -n production
সাধারণ Production সমস্যা ও সমাধান
| সমস্যা |
সমাধান |
| Pod CrashLoopBackOff |
Logs check করুন — সাধারণত configuration, environment variable, বা resource সমস্যা |
| 502 Bad Gateway |
Backend service চালু আছে কিনা এবং health check ঠিক আছে কিনা যাচাই করুন |
| Connection Timeout |
Service-এর endpoint available কিনা, এবং network policy বাধা দিচ্ছে কিনা দেখুন |
| Memory Leak |
kubectl top pods দিয়ে memory usage monitor করুন, প্রয়োজনে limit adjust করুন |
| Pod Pending অবস্থায় আটকে আছে |
Node-এ যথেষ্ট resource আছে কিনা, kubectl describe pod-এর events দেখুন |
Monitoring ও Alerting
Production system-এ সমস্যা হওয়ার সাথে সাথে জানা প্রয়োজন — user-এর অভিযোগের অপেক্ষায় থাকা যাবে
না। এর জন্য ব্যবহৃত হয় monitoring ও alerting tool, যেমন Prometheus (metrics সংগ্রহ) এবং Grafana
(visualization)।
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: product-api-alerts
namespace: production
spec:
groups:
- name: product-api
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
annotations:
summary: "High error rate detected"
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
for: 5m
annotations:
summary: "Pod is crash looping"
- alert: HighMemoryUsage
expr: (sum(container_memory_usage_bytes) by (pod) / 1024^3) > 0.4
for: 5m
annotations:
summary: "Pod memory usage is high"
এই alert-গুলো নিশ্চিত করে যে কোনো সমস্যা হলে team সাথে সাথে জানতে পারে — user অভিযোগ করার আগেই।
এটাই অংশ ১-এ আলোচিত "কোনো Monitoring System ছিল না" সমস্যাটির বাস্তব সমাধান।
✅ অংশ ১২: Best Practices Checklist
এই সিরিজে আলোচিত সবকিছুকে একটি ব্যবহারিক checklist-এ সংক্ষিপ্ত করা যাক।
✓ Testing
প্রতিটি গুরুত্বপূর্ণ function/endpoint-এর জন্য automated test লিখুন। Coverage measure করুন,
কিন্তু শুধু সংখ্যার পেছনে না ছুটে অর্থবহ test লিখুন।
✓ Code Review
কোনো code সরাসরি main/develop-এ merge করবেন না — Pull Request ও review
বাধ্যতামূলক করুন।
✓ CI/CD Automation
Build, test, এবং deployment manual না করে Jenkins/GitHub Actions-এর মতো tool দিয়ে automate করুন।
✓ Environment Parity
Development, Staging, এবং Production যতটা সম্ভব একই রকম রাখুন — একই Docker image, শুধু
configuration আলাদা।
✓ Secrets Management
কোনো secret কখনো code বা Git history-তে hardcode করবেন না।
✓ Health Checks
প্রতিটি service-এ liveness ও readiness endpoint রাখুন, যাতে orchestrator সঠিকভাবে সিদ্ধান্ত নিতে
পারে।
✓ Monitoring ও Alerting
User-এর অভিযোগের আগেই সমস্যা ধরার জন্য monitoring ও alert সেট করুন।
✓ Rollback Plan
নতুন deployment খারাপ হলে দ্রুত আগের version-এ ফিরে যাওয়ার একটি পরীক্ষিত উপায় থাকা উচিত
(kubectl rollout undo)।
🏁 অংশ ১৩: উপসংহার
নবীনের সেই production disaster দিয়ে আমরা শুরু করেছিলাম — একটি automated test, code review, বা
staging environment ছাড়াই সরাসরি production-এ deploy করার পরিণতি। সেখান থেকে আমরা দেখেছি:
✓ Software delivery-এর প্রতিটি ধাপ (development → build → test → package → deploy)
✓ Automated Testing এবং Pytest দিয়ে কীভাবে bug আগেই ধরা যায়
✓ CI ও CD-এর মধ্যে পার্থক্য, এবং Continuous Delivery বনাম Continuous Deployment
✓ Git branching strategy ও Pull Request-এর সম্পূর্ণ lifecycle
✓ Jenkins ও Pipeline as Code (Jenkinsfile) দিয়ে পুরো process automate করা
✓ Configuration ও Secrets কীভাবে নিরাপদে, environment-ভিত্তিকভাবে manage করা হয়
✓ Docker দিয়ে Application ও তার environment প্যাকেজ করা
✓ Kubernetes দিয়ে Production scale-এ deployment পরিচালনা করা
✓ Caddy/reverse proxy এবং Kubernetes Service দিয়ে Networking ও Service Discovery
✓ Production-এ সমস্যা দেখা দিলে কীভাবে systematically debug করা হয়
মূল শিক্ষা: CI/CD কোনো একটি টুল নয় — এটি একটি সংস্কৃতি (culture) এবং প্র্যাকটিস,
যা code থেকে production পর্যন্ত পুরো যাত্রাকে নিরাপদ, দ্রুত এবং repeatable করে তোলে।
নবীন এখন জানে — "It works on my machine" is NOT a deployment strategy। Production-এ
যাওয়ার আগে test, review, staging, এবং monitoring — প্রতিটি ধাপই গুরুত্বপূর্ণ।