diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000000..fa5e3e35089 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,288 @@ +# Apache Ambari Docker Setup + +This directory contains Docker configurations for Apache Ambari, providing containerized environments for development, testing, and production deployment. + +## Quick Start + +### Prerequisites +- Docker 20.10+ +- Docker Compose 2.0+ +- At least 8GB RAM available for Docker + +### Development Environment +```bash +# Clone and build Ambari +git clone https://github.com/apache/ambari.git +cd ambari + +# Start development environment +docker-compose -f docker/docker-compose.dev.yml up -d + +# Access Ambari Web UI +open http://localhost:8080 +# Default credentials: admin/admin +``` + +### Production Deployment +```bash +# Start production stack +docker-compose -f docker/docker-compose.prod.yml up -d + +# Scale agents +docker-compose -f docker/docker-compose.prod.yml up -d --scale ambari-agent=3 +``` + +## Available Images + +### Base Images +- `apache/ambari-base`: Common runtime dependencies +- `apache/ambari-build`: Build environment with Maven, JDK, Node.js + +### Service Images +- `apache/ambari-server`: Ambari Server +- `apache/ambari-agent`: Ambari Agent +- `apache/ambari-metrics`: Metrics Collector with embedded HBase +- `apache/ambari-dev`: Development environment + +### Supporting Images +- `apache/ambari-database`: PostgreSQL with Ambari schema +- `apache/ambari-grafana`: Grafana with Ambari Metrics datasource + +## Build Instructions + +### Build All Images +```bash +# Build all images +./docker/build.sh + +# Build specific image +./docker/build.sh ambari-server + +# Build with custom tag +./docker/build.sh ambari-server --tag myregistry/ambari-server:latest +``` + +### Development Build +```bash +# Build development image with current source +docker build -f docker/Dockerfile.dev -t ambari-dev . + +# Run development container +docker run -it --rm \ + -v $(pwd):/workspace \ + -p 8080:8080 \ + -p 8441:8441 \ + ambari-dev +``` + +## Configuration + +### Environment Variables + +#### Ambari Server +- `AMBARI_DB_HOST`: Database hostname (default: ambari-db) +- `AMBARI_DB_PORT`: Database port (default: 5432) +- `AMBARI_DB_NAME`: Database name (default: ambari) +- `AMBARI_DB_USER`: Database user (default: ambari) +- `AMBARI_DB_PASSWORD`: Database password (default: bigdata) +- `AMBARI_SERVER_HTTPS`: Enable HTTPS (default: false) +- `JAVA_OPTS`: JVM options + +#### Ambari Agent +- `AMBARI_SERVER_HOST`: Ambari Server hostname (default: ambari-server) +- `AMBARI_SERVER_PORT`: Ambari Server port (default: 8080) +- `AGENT_HOSTNAME`: Agent hostname (auto-detected if not set) + +#### Ambari Metrics +- `AMS_HBASE_ROOTDIR`: HBase root directory (default: /var/lib/ambari-metrics-collector/hbase) +- `AMS_COLLECTOR_PORT`: Collector port (default: 6188) +- `AMS_GRAFANA_ENABLED`: Enable Grafana (default: true) + +### Volume Mounts + +#### Persistent Data +- `/var/lib/ambari-server`: Server data and configurations +- `/var/lib/ambari-agent`: Agent data and logs +- `/var/lib/ambari-metrics-collector`: Metrics data +- `/var/log/ambari-*`: Log directories + +#### Development +- `/workspace`: Source code mount point +- `/root/.m2`: Maven repository cache + +## Docker Compose Configurations + +### Development (docker-compose.dev.yml) +- Single-node setup with all services +- Source code mounted for live development +- Debug ports exposed +- Automatic rebuilding enabled + +### Production (docker-compose.prod.yml) +- Multi-container production setup +- Separate database container +- Health checks and restart policies +- Resource limits configured + +### Testing (docker-compose.test.yml) +- Automated testing environment +- Includes test databases and mock services +- CI/CD friendly configuration + +## Networking + +### Default Network +- Network: `ambari-network` (bridge) +- Subnet: `172.20.0.0/16` + +### Service Discovery +Services are accessible by their container names: +- `ambari-server`: Ambari Server +- `ambari-db`: PostgreSQL Database +- `ambari-metrics`: Metrics Collector +- `ambari-grafana`: Grafana Dashboard + +## Health Checks + +All services include health checks: +- **Server**: HTTP check on `/api/v1/clusters` +- **Agent**: Process and heartbeat check +- **Metrics**: HTTP check on `/ws/v1/timeline/metrics` +- **Database**: Connection check + +## Troubleshooting + +### Common Issues + +#### Container Won't Start +```bash +# Check logs +docker-compose logs ambari-server + +# Check container status +docker-compose ps + +# Restart specific service +docker-compose restart ambari-server +``` + +#### Database Connection Issues +```bash +# Verify database is running +docker-compose exec ambari-db pg_isready + +# Check database logs +docker-compose logs ambari-db + +# Reset database +docker-compose down -v +docker-compose up -d ambari-db +``` + +#### Memory Issues +```bash +# Check resource usage +docker stats + +# Increase memory limits in docker-compose.yml +services: + ambari-server: + mem_limit: 4g +``` + +### Debug Mode + +#### Enable Debug Logging +```bash +# Set environment variable +export AMBARI_DEBUG=true +docker-compose up -d + +# Or in docker-compose.yml +environment: + - AMBARI_DEBUG=true +``` + +#### Remote Debugging +```bash +# Server debug port: 5005 +# Agent debug port: 5006 + +# Connect with IDE to localhost:5005 +``` + +## Security Considerations + +### Production Deployment +1. Change default passwords +2. Use external database with proper credentials +3. Enable HTTPS/TLS +4. Configure firewall rules +5. Use secrets management +6. Regular security updates + +### Network Security +```yaml +# Example secure configuration +services: + ambari-server: + environment: + - AMBARI_DB_PASSWORD_FILE=/run/secrets/db_password + secrets: + - db_password + +secrets: + db_password: + external: true +``` + +## Performance Tuning + +### Resource Allocation +```yaml +# Recommended production resources +services: + ambari-server: + mem_limit: 4g + cpus: 2.0 + + ambari-metrics: + mem_limit: 2g + cpus: 1.0 +``` + +### JVM Tuning +```bash +# Server JVM options +JAVA_OPTS="-Xmx2g -Xms1g -XX:+UseG1GC" + +# Metrics JVM options +AMS_JAVA_OPTS="-Xmx1g -Xms512m" +``` + +## Contributing + +### Adding New Services +1. Create Dockerfile in `docker/services/` +2. Add to appropriate docker-compose file +3. Update documentation +4. Add health checks +5. Test thoroughly + +### Testing Changes +```bash +# Run test suite +./docker/test.sh + +# Specific test +./docker/test.sh integration + +# Clean test environment +./docker/test.sh clean +``` + +## Support + +- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/) +- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues) +- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html) diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 00000000000..3f47132d53d --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,558 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Docker Build Script +# This script builds Docker images for Apache Ambari components + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default configuration +DEFAULT_REGISTRY="apache" +DEFAULT_TAG="latest" +DEFAULT_UBUNTU_VERSION="22.04" +DEFAULT_JAVA_VERSION="11" +DEFAULT_MAVEN_VERSION="3.9.6" +DEFAULT_NODE_VERSION="18" + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Available images +AVAILABLE_IMAGES=( + "base" + "server" + "agent" + "metrics" + "dev" + "all" +) + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Docker Build Script + +Usage: $0 [OPTIONS] [IMAGE_NAME] + +Available Images: + base - Base image with common dependencies + server - Ambari Server image + agent - Ambari Agent image + metrics - Ambari Metrics Collector image + dev - Development environment image + all - Build all images + +Options: + -r, --registry REGISTRY Docker registry prefix (default: $DEFAULT_REGISTRY) + -t, --tag TAG Image tag (default: $DEFAULT_TAG) + --ubuntu-version VERSION Ubuntu base image version (default: $DEFAULT_UBUNTU_VERSION) + --java-version VERSION Java version (default: $DEFAULT_JAVA_VERSION) + --maven-version VERSION Maven version (default: $DEFAULT_MAVEN_VERSION) + --node-version VERSION Node.js version (default: $DEFAULT_NODE_VERSION) + --no-cache Build without using cache + --push Push images to registry after building + --parallel Build images in parallel (when building all) + --target TARGET Build specific target (runtime, build, development) + --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64) + -v, --verbose Enable verbose output + -h, --help Show this help message + +Examples: + $0 base # Build base image + $0 server --tag 3.0.0 # Build server image with custom tag + $0 all --registry myregistry --push # Build and push all images + $0 dev --no-cache --verbose # Build dev image without cache + $0 server --platform linux/amd64,linux/arm64 # Multi-platform build + +Environment Variables: + DOCKER_REGISTRY Default registry (overrides -r) + DOCKER_TAG Default tag (overrides -t) + DOCKER_BUILDKIT Enable BuildKit (recommended: 1) + DEBUG Enable debug output (true/false) + +EOF +} + +# Function to parse command line arguments +parse_args() { + REGISTRY="${DOCKER_REGISTRY:-$DEFAULT_REGISTRY}" + TAG="${DOCKER_TAG:-$DEFAULT_TAG}" + UBUNTU_VERSION="$DEFAULT_UBUNTU_VERSION" + JAVA_VERSION="$DEFAULT_JAVA_VERSION" + MAVEN_VERSION="$DEFAULT_MAVEN_VERSION" + NODE_VERSION="$DEFAULT_NODE_VERSION" + NO_CACHE="" + PUSH=false + PARALLEL=false + TARGET="" + PLATFORM="" + VERBOSE=false + IMAGE_NAME="" + + while [[ $# -gt 0 ]]; do + case $1 in + -r|--registry) + REGISTRY="$2" + shift 2 + ;; + -t|--tag) + TAG="$2" + shift 2 + ;; + --ubuntu-version) + UBUNTU_VERSION="$2" + shift 2 + ;; + --java-version) + JAVA_VERSION="$2" + shift 2 + ;; + --maven-version) + MAVEN_VERSION="$2" + shift 2 + ;; + --node-version) + NODE_VERSION="$2" + shift 2 + ;; + --no-cache) + NO_CACHE="--no-cache" + shift + ;; + --push) + PUSH=true + shift + ;; + --parallel) + PARALLEL=true + shift + ;; + --target) + TARGET="$2" + shift 2 + ;; + --platform) + PLATFORM="$2" + shift 2 + ;; + -v|--verbose) + VERBOSE=true + DEBUG=true + shift + ;; + -h|--help) + show_usage + exit 0 + ;; + -*) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + *) + if [[ -z "$IMAGE_NAME" ]]; then + IMAGE_NAME="$1" + else + log_error "Multiple image names specified: $IMAGE_NAME and $1" + exit 1 + fi + shift + ;; + esac + done + + # Validate image name + if [[ -z "$IMAGE_NAME" ]]; then + log_error "No image name specified" + show_usage + exit 1 + fi + + if [[ ! " ${AVAILABLE_IMAGES[@]} " =~ " ${IMAGE_NAME} " ]]; then + log_error "Invalid image name: $IMAGE_NAME" + log_error "Available images: ${AVAILABLE_IMAGES[*]}" + exit 1 + fi +} + +# Function to build Docker image +build_image() { + local image_name=$1 + local dockerfile=$2 + local context=${3:-$PROJECT_ROOT} + local extra_args=("${@:4}") + + local full_image_name="${REGISTRY}/ambari-${image_name}:${TAG}" + + log_info "Building image: $full_image_name" + log_debug "Dockerfile: $dockerfile" + log_debug "Context: $context" + + # Prepare build arguments + local build_args=( + "--build-arg" "UBUNTU_VERSION=$UBUNTU_VERSION" + "--build-arg" "JAVA_VERSION=$JAVA_VERSION" + "--build-arg" "MAVEN_VERSION=$MAVEN_VERSION" + "--build-arg" "NODE_VERSION=$NODE_VERSION" + ) + + # Add target if specified + if [[ -n "$TARGET" ]]; then + build_args+=("--target" "$TARGET") + fi + + # Add platform if specified + if [[ -n "$PLATFORM" ]]; then + build_args+=("--platform" "$PLATFORM") + fi + + # Add no-cache if specified + if [[ -n "$NO_CACHE" ]]; then + build_args+=("$NO_CACHE") + fi + + # Add extra arguments + build_args+=("${extra_args[@]}") + + # Build command + local build_cmd=( + "docker" "build" + "${build_args[@]}" + "-f" "$dockerfile" + "-t" "$full_image_name" + "$context" + ) + + if [[ "$VERBOSE" == "true" ]]; then + log_debug "Build command: ${build_cmd[*]}" + fi + + # Execute build + if "${build_cmd[@]}"; then + log_info "Successfully built: $full_image_name" + + # Push if requested + if [[ "$PUSH" == "true" ]]; then + log_info "Pushing image: $full_image_name" + if docker push "$full_image_name"; then + log_info "Successfully pushed: $full_image_name" + else + log_error "Failed to push: $full_image_name" + return 1 + fi + fi + + return 0 + else + log_error "Failed to build: $full_image_name" + return 1 + fi +} + +# Function to build base image +build_base() { + log_info "Building Ambari base image..." + build_image "base" "$SCRIPT_DIR/Dockerfile.base" +} + +# Function to build server image +build_server() { + log_info "Building Ambari server image..." + + # Create server Dockerfile if it doesn't exist + local server_dockerfile="$SCRIPT_DIR/Dockerfile.server" + if [[ ! -f "$server_dockerfile" ]]; then + log_info "Creating server Dockerfile..." + cat > "$server_dockerfile" << 'EOF' +# Apache Ambari Server Image +FROM apache/ambari-base:latest as base + +# Switch to root for installation +USER root + +# Install Ambari Server +COPY ambari-server/target/rpm/ambari-server/RPMS/x86_64/*.rpm /tmp/ +RUN yum install -y /tmp/ambari-server-*.rpm && \ + rm -f /tmp/*.rpm + +# Server configuration +COPY docker/config/server/ /etc/ambari-server/conf/ + +# Switch back to ambari user +USER ambari + +# Expose server ports +EXPOSE 8080 8441 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Default command +CMD ["ambari-server", "start"] +EOF + fi + + build_image "server" "$server_dockerfile" +} + +# Function to build agent image +build_agent() { + log_info "Building Ambari agent image..." + + # Create agent Dockerfile if it doesn't exist + local agent_dockerfile="$SCRIPT_DIR/Dockerfile.agent" + if [[ ! -f "$agent_dockerfile" ]]; then + log_info "Creating agent Dockerfile..." + cat > "$agent_dockerfile" << 'EOF' +# Apache Ambari Agent Image +FROM apache/ambari-base:latest as base + +# Switch to root for installation +USER root + +# Install Ambari Agent +COPY ambari-agent/target/rpm/ambari-agent/RPMS/x86_64/*.rpm /tmp/ +RUN yum install -y /tmp/ambari-agent-*.rpm && \ + rm -f /tmp/*.rpm + +# Agent configuration +COPY docker/config/agent/ /etc/ambari-agent/conf/ + +# Switch back to ambari user +USER ambari + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Default command +CMD ["ambari-agent", "start"] +EOF + fi + + build_image "agent" "$agent_dockerfile" +} + +# Function to build metrics image +build_metrics() { + log_info "Building Ambari metrics image..." + + # Create metrics Dockerfile if it doesn't exist + local metrics_dockerfile="$SCRIPT_DIR/Dockerfile.metrics" + if [[ ! -f "$metrics_dockerfile" ]]; then + log_info "Creating metrics Dockerfile..." + cat > "$metrics_dockerfile" << 'EOF' +# Apache Ambari Metrics Image +FROM apache/ambari-base:latest as base + +# Switch to root for installation +USER root + +# Install Ambari Metrics packages +COPY ambari-metrics/ambari-metrics-assembly/target/ambari-metrics-assembly-*.tar.gz /tmp/ +RUN cd /tmp && \ + tar -xzf ambari-metrics-assembly-*.tar.gz && \ + mv ambari-metrics-assembly-* /opt/ambari-metrics && \ + rm -f /tmp/*.tar.gz + +# Metrics configuration +COPY docker/config/metrics/ /etc/ambari-metrics-collector/conf/ + +# Switch back to ambari user +USER ambari + +# Expose metrics ports +EXPOSE 6188 61888 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Default command +CMD ["ambari-metrics-collector", "start"] +EOF + fi + + build_image "metrics" "$metrics_dockerfile" +} + +# Function to build development image +build_dev() { + log_info "Building Ambari development image..." + build_image "dev" "$SCRIPT_DIR/Dockerfile.base" "$PROJECT_ROOT" "--target" "build" +} + +# Function to build all images +build_all() { + log_info "Building all Ambari images..." + + local images=("base" "server" "agent" "metrics" "dev") + local failed_images=() + + if [[ "$PARALLEL" == "true" ]]; then + log_info "Building images in parallel..." + local pids=() + + for image in "${images[@]}"; do + ( + case $image in + "base") build_base ;; + "server") build_server ;; + "agent") build_agent ;; + "metrics") build_metrics ;; + "dev") build_dev ;; + esac + ) & + pids+=($!) + done + + # Wait for all builds to complete + for i in "${!pids[@]}"; do + if ! wait "${pids[$i]}"; then + failed_images+=("${images[$i]}") + fi + done + else + log_info "Building images sequentially..." + for image in "${images[@]}"; do + case $image in + "base") build_base || failed_images+=("$image") ;; + "server") build_server || failed_images+=("$image") ;; + "agent") build_agent || failed_images+=("$image") ;; + "metrics") build_metrics || failed_images+=("$image") ;; + "dev") build_dev || failed_images+=("$image") ;; + esac + done + fi + + # Report results + if [[ ${#failed_images[@]} -eq 0 ]]; then + log_info "All images built successfully!" + else + log_error "Failed to build images: ${failed_images[*]}" + return 1 + fi +} + +# Function to check prerequisites +check_prerequisites() { + log_info "Checking prerequisites..." + + # Check Docker + if ! command -v docker >/dev/null 2>&1; then + log_error "Docker is not installed or not in PATH" + exit 1 + fi + + # Check Docker daemon + if ! docker info >/dev/null 2>&1; then + log_error "Docker daemon is not running" + exit 1 + fi + + # Check BuildKit (recommended) + if [[ "${DOCKER_BUILDKIT:-}" != "1" ]]; then + log_warn "DOCKER_BUILDKIT is not enabled. Consider setting DOCKER_BUILDKIT=1 for better performance" + fi + + # Check project structure + if [[ ! -f "$PROJECT_ROOT/pom.xml" ]]; then + log_error "Not in Ambari project root directory" + exit 1 + fi + + log_info "Prerequisites check passed" +} + +# Main function +main() { + log_info "Apache Ambari Docker Build Script" + log_info "================================" + + # Parse arguments + parse_args "$@" + + # Check prerequisites + check_prerequisites + + # Show configuration + log_info "Configuration:" + log_info " Registry: $REGISTRY" + log_info " Tag: $TAG" + log_info " Ubuntu Version: $UBUNTU_VERSION" + log_info " Java Version: $JAVA_VERSION" + log_info " Maven Version: $MAVEN_VERSION" + log_info " Node.js Version: $NODE_VERSION" + log_info " Image: $IMAGE_NAME" + if [[ -n "$TARGET" ]]; then + log_info " Target: $TARGET" + fi + if [[ -n "$PLATFORM" ]]; then + log_info " Platform: $PLATFORM" + fi + log_info "" + + # Build image(s) + case $IMAGE_NAME in + "base") build_base ;; + "server") build_server ;; + "agent") build_agent ;; + "metrics") build_metrics ;; + "dev") build_dev ;; + "all") build_all ;; + *) + log_error "Unknown image: $IMAGE_NAME" + exit 1 + ;; + esac + + log_info "Build completed successfully!" +} + +# Run main function +main "$@" diff --git a/docker/config/agent/ambari-agent.ini b/docker/config/agent/ambari-agent.ini new file mode 100644 index 00000000000..96420480154 --- /dev/null +++ b/docker/config/agent/ambari-agent.ini @@ -0,0 +1,24 @@ +[server] +hostname=ambari-server +url_port=8080 +secured_url_port=8441 + +[agent] +prefix=/var/lib/ambari-agent/data +cache_dir=/var/lib/ambari-agent/cache +log_dir=/var/log/ambari-agent +pidfile=/var/run/ambari-agent/ambari-agent.pid +hostname_script=/var/lib/ambari-agent/hostname.sh + +[security] +keysdir=/var/lib/ambari-agent/keys +server_crt=ca.crt +passphrase_env_var_name=AMBARI_PASSPHRASE + +[heartbeat] +state_interval=6 +dirs=/etc/hadoop,/etc/hadoop/conf,/etc/hbase,/etc/hcatalog,/etc/hive,/etc/oozie,/etc/sqloop,/var/run/hadoop,/var/run/zookeeper,/var/run/hbase,/var/run/hive,/var/run/oozie,/var/log/hadoop,/var/log/zookeeper,/var/log/hbase,/var/log/hive,/var/log/oozie +rpms=hadoop,zookeeper,hbase,hive + +[logging] +syslog_enabled=0 diff --git a/docker/config/metrics/ams-site.xml b/docker/config/metrics/ams-site.xml new file mode 100644 index 00000000000..8a3dba92ce6 --- /dev/null +++ b/docker/config/metrics/ams-site.xml @@ -0,0 +1,62 @@ + + + + timeline.service.address + 0.0.0.0:6188 + Timeline service address + + + + timeline.service.webapp.address + 0.0.0.0:6188 + Timeline service webapp address + + + + timeline.service.webapp.https.address + 0.0.0.0:61889 + Timeline service webapp https address + + + + timeline.metrics.service.default.result.limit + 15840 + Default limit of number of result rows + + + + timeline.metrics.service.checkpointDelay + 60 + Time in seconds to sleep on the first run or when the checkpoint directory is empty + + + + timeline.metrics.service.resultset.fetchSize + 2000 + JDBC resultset fetch size + + + + timeline.metrics.cluster.aggregator.hourly.interval + 3600 + Time in seconds to aggregate hourly data + + + + timeline.metrics.cluster.aggregator.daily.interval + 86400 + Time in seconds to aggregate daily data + + + + timeline.metrics.host.aggregator.hourly.interval + 3600 + Time in seconds to aggregate hourly host data + + + + timeline.metrics.host.aggregator.daily.interval + 86400 + Time in seconds to aggregate daily host data + + diff --git a/docker/config/server/ambari.properties b/docker/config/server/ambari.properties new file mode 100644 index 00000000000..7c9572cdde1 --- /dev/null +++ b/docker/config/server/ambari.properties @@ -0,0 +1,37 @@ +# Apache Ambari Server Configuration +# This file contains default configuration for Ambari Server in Docker + +# Database Configuration +server.jdbc.driver=org.postgresql.Driver +server.jdbc.url=jdbc:postgresql://ambari-db:5432/ambari +server.jdbc.user.name=ambari +server.jdbc.user.passwd=bigdata + +# Server Configuration +server.persistence.type=remote +server.connection.max.idle.millis=900000 + +# Security Configuration +security.server.two_way_ssl=false +security.server.cert_name=ca.crt +security.server.key_name=ca.key + +# API Configuration +api.authenticated.user=admin +api.ssl=false + +# Views Configuration +views.dir=/var/lib/ambari-server/resources/views +views.validate=false + +# Logging Configuration +logging.level.root=INFO +logging.level.org.apache.ambari=INFO + +# Cluster Configuration +cluster.monitoring.enabled=true +cluster.secured.state=UNSECURED + +# Agent Configuration +agent.package.install.task.timeout=1800 +agent.task.timeout=900 diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml new file mode 100644 index 00000000000..3bef09a5897 --- /dev/null +++ b/docker/docker-compose.dev.yml @@ -0,0 +1,303 @@ +# Apache Ambari Development Docker Compose Configuration +# This configuration provides a complete development environment for Ambari + +version: '3.8' + +services: + # PostgreSQL Database for Ambari + ambari-db: + image: postgres:15-alpine + container_name: ambari-db + hostname: ambari-db + environment: + POSTGRES_DB: ambari + POSTGRES_USER: ambari + POSTGRES_PASSWORD: bigdata + POSTGRES_INITDB_ARGS: "--encoding=UTF8" + volumes: + - ambari-db-data:/var/lib/postgresql/data + - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro + ports: + - "5432:5432" + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + + # Ambari Server + ambari-server: + build: + context: .. + dockerfile: docker/images/ambari/Dockerfile.server + target: development + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=8 + - MAVEN_VERSION=3.9.6 + container_name: ambari-server + hostname: ambari-server + environment: + # Database configuration + - AMBARI_DB_HOST=ambari-db + - AMBARI_DB_PORT=5432 + - AMBARI_DB_NAME=ambari + - AMBARI_DB_USER=ambari + - AMBARI_DB_PASSWORD=bigdata + + # Server configuration + - AMBARI_SERVER_HTTPS=false + - AMBARI_COMPONENT=server + + # Development settings + - AMBARI_DEBUG=true + - MAVEN_OPTS=-Xmx2g -XX:+UseG1GC + - JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 + volumes: + # Source code mount for live development + - ../:/workspace:cached + - ambari-server-data:/var/lib/ambari-server + - ambari-server-logs:/var/log/ambari-server + - ambari-server-conf:/etc/ambari-server/conf + # Maven cache for faster builds + - maven-cache:/home/ambari/.m2 + # SSH keys for multi-node communication + - ssh-keys:/home/ambari/.ssh + ports: + - "8080:8080" # Ambari Web UI + - "8441:8441" # Ambari HTTPS + - "5005:5005" # Java Debug Port + networks: + - ambari-network + depends_on: + ambari-db: + condition: service_healthy + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 120s + restart: unless-stopped + stdin_open: true + tty: true + + # Ambari Agent (can be scaled) + ambari-agent: + build: + context: .. + dockerfile: docker/images/ambari/Dockerfile.agent + target: development + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=8 + container_name: ambari-agent-1 + hostname: ambari-agent-1 + environment: + # Server connection + - AMBARI_SERVER_HOST=ambari-server + - AMBARI_SERVER_PORT=8080 + - AMBARI_COMPONENT=agent + + # Agent configuration + - AGENT_HOSTNAME=ambari-agent-1 + + # Development settings + - AMBARI_DEBUG=true + - JAVA_OPTS=-Xmx1g -Xms512m -XX:+UseG1GC -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006 + volumes: + # Source code mount for development + - ../:/workspace:cached + - ambari-agent-data:/var/lib/ambari-agent + - ambari-agent-logs:/var/log/ambari-agent + - ambari-agent-conf:/etc/ambari-agent/conf + # Shared SSH keys + - ssh-keys:/home/ambari/.ssh:ro + ports: + - "5006:5006" # Java Debug Port + networks: + - ambari-network + depends_on: + - ambari-server + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + privileged: true # Required for some agent operations + stdin_open: true + tty: true + + # Ambari Metrics Collector (Optional - controlled by METRICS_ENABLED) + ambari-metrics: + build: + context: .. + dockerfile: docker/images/ambari-metrics/Dockerfile + target: development + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=8 + container_name: ambari-metrics + hostname: ambari-metrics + environment: + # Metrics configuration + - AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase + - AMS_COLLECTOR_PORT=6188 + - AMS_GRAFANA_ENABLED=true + - AMBARI_COMPONENT=metrics + + # Development settings + - AMBARI_DEBUG=true + - AMS_JAVA_OPTS=-Xmx1g -Xms512m -XX:+UseG1GC + volumes: + # Source code mount for development + - ../:/workspace:cached + - ambari-metrics-data:/var/lib/ambari-metrics-collector + - ambari-metrics-logs:/var/log/ambari-metrics-collector + - ambari-metrics-conf:/etc/ambari-metrics-collector/conf + ports: + - "6188:6188" # Metrics Collector API + - "61888:61888" # Metrics aggregation port + networks: + - ambari-network + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 90s + restart: unless-stopped + stdin_open: true + tty: true + profiles: + - metrics + deploy: + replicas: ${METRICS_ENABLED:-0} # Default to 0, meaning metrics won't start unless METRICS_ENABLED is set + + # Grafana for Metrics Visualization (Optional - controlled by GRAFANA_ENABLED) + grafana: + image: grafana/grafana:10.2.0 + container_name: ambari-grafana + hostname: grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource + - GF_USERS_ALLOW_SIGN_UP=false + - GF_SERVER_ROOT_URL=http://localhost:3000 + volumes: + - grafana-data:/var/lib/grafana + - ./config/grafana/provisioning:/etc/grafana/provisioning:ro + - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro + ports: + - "3000:3000" # Grafana Web UI + networks: + - ambari-network + depends_on: + - ambari-metrics + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + restart: unless-stopped + profiles: + - metrics + deploy: + replicas: ${GRAFANA_ENABLED:-0} # Default to 0, controlled by GRAFANA_ENABLED + + # Development Tools Container + dev-tools: + build: + context: .. + dockerfile: docker/images/ambari-base/Dockerfile + target: build + container_name: ambari-dev-tools + hostname: dev-tools + environment: + - AMBARI_DEBUG=true + volumes: + # Source code mount + - ../:/workspace:cached + # Maven cache + - maven-cache:/home/ambari/.m2 + # Build artifacts + - build-cache:/workspace/target + working_dir: /workspace + networks: + - ambari-network + profiles: + - dev-tools + stdin_open: true + tty: true + command: ["bash"] + +# Networks +networks: + ambari-network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 + +# Volumes +volumes: + # Database + ambari-db-data: + driver: local + + # Ambari Server + ambari-server-data: + driver: local + ambari-server-logs: + driver: local + ambari-server-conf: + driver: local + + # Ambari Agent + ambari-agent-data: + driver: local + ambari-agent-logs: + driver: local + ambari-agent-conf: + driver: local + + # Ambari Metrics + ambari-metrics-data: + driver: local + ambari-metrics-logs: + driver: local + ambari-metrics-conf: + driver: local + + # Grafana + grafana-data: + driver: local + + # Shared volumes + maven-cache: + driver: local + ssh-keys: + driver: local + build-cache: + driver: local + +# Development specific configurations +x-development-overrides: + # Common development settings + &dev-common + restart: "no" # Don't restart automatically in dev + + # Volume mount for live development + &source-mount + - ../:/workspace:cached + + # Debug port configuration + &debug-ports + - "5005:5005" # Server debug + - "5006:5006" # Agent debug diff --git a/docker/docker-compose.minimal.yml b/docker/docker-compose.minimal.yml new file mode 100644 index 00000000000..3d01f1e7104 --- /dev/null +++ b/docker/docker-compose.minimal.yml @@ -0,0 +1,102 @@ +# Minimal Apache Ambari Docker Compose Configuration +# This setup focuses on core infrastructure that works on ARM64 Macs + +version: '3.8' + +services: + # PostgreSQL Database for Ambari + ambari-db: + image: postgres:15-alpine + container_name: ambari-database + hostname: ambari-db + environment: + POSTGRES_DB: ambari + POSTGRES_USER: ambari + POSTGRES_PASSWORD: bigdata + POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" + volumes: + - ambari-db-data:/var/lib/postgresql/data + - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro + ports: + - "5433:5432" # Changed port to avoid conflicts + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + restart: unless-stopped + + # Zookeeper for coordination + zookeeper: + image: confluentinc/cp-zookeeper:7.4.0 + container_name: ambari-zookeeper + hostname: zookeeper + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + ZOOKEEPER_INIT_LIMIT: 5 + ZOOKEEPER_SYNC_LIMIT: 2 + volumes: + - zookeeper-data:/var/lib/zookeeper/data + - zookeeper-logs:/var/lib/zookeeper/log + ports: + - "2182:2181" # Changed port to avoid conflicts + networks: + - ambari-network + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "2181"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + restart: unless-stopped + + # Grafana for visualization + grafana: + image: grafana/grafana:10.2.0 + container_name: ambari-grafana-test + hostname: grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - GF_SERVER_ROOT_URL=http://localhost:3002 + volumes: + - grafana-data:/var/lib/grafana + ports: + - "3002:3000" # Changed port to avoid conflicts + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + restart: unless-stopped + +# Networks +networks: + ambari-network: + driver: bridge + ipam: + config: + - subnet: 172.21.0.0/16 + +# Volumes +volumes: + # Database + ambari-db-data: + driver: local + + # Zookeeper + zookeeper-data: + driver: local + zookeeper-logs: + driver: local + + # Grafana + grafana-data: + driver: local diff --git a/docker/docker-compose.simple.yml b/docker/docker-compose.simple.yml new file mode 100644 index 00000000000..d268710d0dd --- /dev/null +++ b/docker/docker-compose.simple.yml @@ -0,0 +1,191 @@ +# Simplified Apache Ambari Docker Compose Configuration +# This setup uses existing images and focuses on getting Ambari running quickly + +version: '3.8' + +services: + # PostgreSQL Database for Ambari + ambari-db: + image: postgres:15-alpine + container_name: ambari-database + hostname: ambari-db + environment: + POSTGRES_DB: ambari + POSTGRES_USER: ambari + POSTGRES_PASSWORD: bigdata + POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" + volumes: + - ambari-db-data:/var/lib/postgresql/data + - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro + ports: + - "5432:5432" + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + restart: unless-stopped + + # Zookeeper for coordination + zookeeper: + image: confluentinc/cp-zookeeper:7.4.0 + container_name: ambari-zookeeper + hostname: zookeeper + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + ZOOKEEPER_INIT_LIMIT: 5 + ZOOKEEPER_SYNC_LIMIT: 2 + volumes: + - zookeeper-data:/var/lib/zookeeper/data + - zookeeper-logs:/var/lib/zookeeper/log + ports: + - "2181:2181" + networks: + - ambari-network + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "2181"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + restart: unless-stopped + + # Hadoop NameNode + namenode: + image: apache/hadoop:3.3.6 + container_name: hadoop-namenode + hostname: namenode + environment: + - CLUSTER_NAME=ambari-cluster + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - CORE_CONF_hadoop_http_staticuser_user=root + - HDFS_CONF_dfs_webhdfs_enabled=true + - HDFS_CONF_dfs_permissions_enabled=false + - HDFS_CONF_dfs_replication=1 + volumes: + - namenode-data:/hadoop/dfs/name + ports: + - "9870:9870" # NameNode Web UI + - "9001:9000" # NameNode IPC (changed to avoid conflict) + networks: + - ambari-network + command: ["hdfs", "namenode"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9870"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + + # Hadoop DataNode + datanode: + image: apache/hadoop:3.3.6 + container_name: hadoop-datanode + hostname: datanode + depends_on: + namenode: + condition: service_healthy + environment: + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - HDFS_CONF_dfs_webhdfs_enabled=true + - HDFS_CONF_dfs_permissions_enabled=false + - HDFS_CONF_dfs_datanode_use_datanode_hostname=false + volumes: + - datanode-data:/hadoop/dfs/data + ports: + - "9864:9864" # DataNode Web UI + networks: + - ambari-network + command: ["hdfs", "datanode"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9864"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + + # YARN ResourceManager + resourcemanager: + image: apache/hadoop:3.3.6 + container_name: hadoop-resourcemanager + hostname: resourcemanager + depends_on: + namenode: + condition: service_healthy + environment: + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - YARN_CONF_yarn_resourcemanager_hostname=resourcemanager + - YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032 + - YARN_CONF_yarn_resourcemanager_webapp_address=resourcemanager:8088 + ports: + - "8088:8088" # ResourceManager Web UI + - "8032:8032" # ResourceManager IPC + networks: + - ambari-network + command: ["yarn", "resourcemanager"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8088"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + + # Grafana for visualization + grafana: + image: grafana/grafana:10.2.0 + container_name: ambari-grafana + hostname: grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - GF_SERVER_ROOT_URL=http://localhost:3000 + volumes: + - grafana-data:/var/lib/grafana + ports: + - "3001:3000" # Changed to avoid conflict with existing Grafana + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + restart: unless-stopped + +# Networks +networks: + ambari-network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 + +# Volumes +volumes: + # Database + ambari-db-data: + driver: local + + # Zookeeper + zookeeper-data: + driver: local + zookeeper-logs: + driver: local + + # Hadoop + namenode-data: + driver: local + datanode-data: + driver: local + + # Grafana + grafana-data: + driver: local diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000000..d6c16a914a0 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,396 @@ +# Apache Ambari Production Docker Compose Configuration +# Based on best practices from Apache Pinot and other Apache projects + +version: '3.8' + +services: + # Zookeeper for coordination (following Pinot pattern) + zookeeper: + image: confluentinc/cp-zookeeper:7.4.0 + container_name: ambari-zookeeper + hostname: zookeeper + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + ZOOKEEPER_INIT_LIMIT: 5 + ZOOKEEPER_SYNC_LIMIT: 2 + ZOOKEEPER_MAX_CLIENT_CNXNS: 60 + ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT: 3 + ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: 24 + volumes: + - zookeeper-data:/var/lib/zookeeper/data + - zookeeper-logs:/var/lib/zookeeper/log + ports: + - "2181:2181" + networks: + - ambari-network + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "2181"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s + restart: unless-stopped + + # PostgreSQL Database for Ambari + ambari-db: + image: postgres:15-alpine + container_name: ambari-database + hostname: ambari-db + environment: + POSTGRES_DB: ambari + POSTGRES_USER: ambari + POSTGRES_PASSWORD: bigdata + POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" + PGDATA: /var/lib/postgresql/data/pgdata + volumes: + - ambari-db-data:/var/lib/postgresql/data + - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro + ports: + - "5432:5432" + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + restart: unless-stopped + command: > + postgres + -c max_connections=200 + -c shared_buffers=256MB + -c effective_cache_size=1GB + -c maintenance_work_mem=64MB + -c checkpoint_completion_target=0.9 + -c wal_buffers=16MB + -c default_statistics_target=100 + + # Ambari Server + ambari-server: + build: + context: .. + dockerfile: docker/Dockerfile.server + target: runtime + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=11 + - MAVEN_VERSION=3.9.6 + container_name: ambari-server + hostname: ambari-server + depends_on: + ambari-db: + condition: service_healthy + zookeeper: + condition: service_healthy + environment: + # Database configuration + - AMBARI_DB_HOST=ambari-db + - AMBARI_DB_PORT=5432 + - AMBARI_DB_NAME=ambari + - AMBARI_DB_USER=ambari + - AMBARI_DB_PASSWORD=bigdata + + # Server configuration + - AMBARI_SERVER_HTTPS=false + - AMBARI_COMPONENT=server + + # JVM configuration (following Pinot pattern) + - JAVA_OPTS=-Xmx4G -Xms2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+UseZGC + + # Zookeeper configuration + - AMBARI_ZK_CONNECT=zookeeper:2181 + volumes: + - ambari-server-data:/var/lib/ambari-server + - ambari-server-logs:/var/log/ambari-server + - ambari-server-conf:/etc/ambari-server/conf + ports: + - "8080:8080" # Ambari Web UI + - "8441:8441" # Ambari HTTPS + networks: + - ambari-network + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh", "server"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + restart: unless-stopped + deploy: + resources: + limits: + memory: 6G + cpus: '2.0' + reservations: + memory: 4G + cpus: '1.0' + + # Ambari Agent (scalable) + ambari-agent: + build: + context: .. + dockerfile: docker/Dockerfile.agent + target: runtime + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=11 + hostname: ambari-agent-{{.Task.Slot}} + depends_on: + ambari-server: + condition: service_healthy + environment: + # Server connection + - AMBARI_SERVER_HOST=ambari-server + - AMBARI_SERVER_PORT=8080 + - AMBARI_COMPONENT=agent + + # JVM configuration + - JAVA_OPTS=-Xmx2G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 + volumes: + - ambari-agent-data:/var/lib/ambari-agent + - ambari-agent-logs:/var/log/ambari-agent + - ambari-agent-conf:/etc/ambari-agent/conf + networks: + - ambari-network + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh", "agent"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + privileged: true + deploy: + replicas: 1 + resources: + limits: + memory: 3G + cpus: '1.0' + reservations: + memory: 2G + cpus: '0.5' + + # Ambari Metrics Collector + ambari-metrics: + build: + context: .. + dockerfile: docker/Dockerfile.metrics + target: runtime + args: + - UBUNTU_VERSION=22.04 + - JAVA_VERSION=11 + container_name: ambari-metrics-collector + hostname: ambari-metrics + depends_on: + ambari-server: + condition: service_healthy + environment: + # Metrics configuration + - AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase + - AMS_COLLECTOR_PORT=6188 + - AMBARI_COMPONENT=metrics + + # JVM configuration (following Pinot pattern) + - AMS_JAVA_OPTS=-Xmx2G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 + - HBASE_HEAPSIZE=1024m + volumes: + - ambari-metrics-data:/var/lib/ambari-metrics-collector + - ambari-metrics-logs:/var/log/ambari-metrics-collector + - ambari-metrics-conf:/etc/ambari-metrics-collector/conf + ports: + - "6188:6188" # Metrics Collector API + - "61888:61888" # Metrics aggregation port + networks: + - ambari-network + healthcheck: + test: ["CMD", "/usr/local/bin/health-check.sh", "metrics"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 90s + restart: unless-stopped + deploy: + resources: + limits: + memory: 3G + cpus: '1.0' + reservations: + memory: 2G + cpus: '0.5' + + # Grafana for Metrics Visualization (following Pinot pattern) + grafana: + image: grafana/grafana:10.2.0 + container_name: ambari-grafana + hostname: grafana + depends_on: + - ambari-metrics + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_USERS_ALLOW_SIGN_UP=false + - GF_SERVER_ROOT_URL=http://localhost:3000 + - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource + - GF_SECURITY_ALLOW_EMBEDDING=true + volumes: + - grafana-data:/var/lib/grafana + - ./config/grafana/provisioning:/etc/grafana/provisioning:ro + - ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro + ports: + - "3000:3000" + networks: + - ambari-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + restart: unless-stopped + + # Hadoop NameNode (for cluster setup) + namenode: + image: apache/hadoop:3.3.6 + container_name: hadoop-namenode + hostname: namenode + environment: + - CLUSTER_NAME=ambari-cluster + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - CORE_CONF_hadoop_http_staticuser_user=root + - CORE_CONF_hadoop_proxyuser_hue_hosts=* + - CORE_CONF_hadoop_proxyuser_hue_groups=* + - HDFS_CONF_dfs_webhdfs_enabled=true + - HDFS_CONF_dfs_permissions_enabled=false + - HDFS_CONF_dfs_nameservices=mycluster + - HDFS_CONF_dfs_replication=2 + volumes: + - namenode-data:/hadoop/dfs/name + ports: + - "9870:9870" # NameNode Web UI + - "9001:9000" # NameNode IPC (changed to avoid conflict) + networks: + - ambari-network + command: ["hdfs", "namenode"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9870"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + + # Hadoop DataNode (scalable) + datanode: + image: apache/hadoop:3.3.6 + hostname: datanode-{{.Task.Slot}} + depends_on: + namenode: + condition: service_healthy + environment: + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - CORE_CONF_hadoop_http_staticuser_user=root + - HDFS_CONF_dfs_webhdfs_enabled=true + - HDFS_CONF_dfs_permissions_enabled=false + - HDFS_CONF_dfs_datanode_use_datanode_hostname=false + - HDFS_CONF_dfs_client_use_datanode_hostname=false + - HDFS_CONF_dfs_datanode_data_dir=/hadoop/dfs/data + volumes: + - datanode-data:/hadoop/dfs/data + ports: + - "9864" # DataNode Web UI (dynamic port) + networks: + - ambari-network + command: ["hdfs", "datanode"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9864"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + deploy: + replicas: 2 + + # YARN ResourceManager + resourcemanager: + image: apache/hadoop:3.3.6 + container_name: hadoop-resourcemanager + hostname: resourcemanager + depends_on: + namenode: + condition: service_healthy + environment: + - CORE_CONF_fs_defaultFS=hdfs://namenode:9000 + - YARN_CONF_yarn_resourcemanager_hostname=resourcemanager + - YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032 + - YARN_CONF_yarn_resourcemanager_scheduler_address=resourcemanager:8030 + - YARN_CONF_yarn_resourcemanager_resource_tracker_address=resourcemanager:8031 + - YARN_CONF_yarn_resourcemanager_admin_address=resourcemanager:8033 + - YARN_CONF_yarn_resourcemanager_webapp_address=resourcemanager:8088 + ports: + - "8088:8088" # ResourceManager Web UI + - "8032:8032" # ResourceManager IPC + networks: + - ambari-network + command: ["yarn", "resourcemanager"] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8088"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + restart: unless-stopped + +# Networks +networks: + ambari-network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 + +# Volumes +volumes: + # Zookeeper + zookeeper-data: + driver: local + zookeeper-logs: + driver: local + + # Database + ambari-db-data: + driver: local + + # Ambari Server + ambari-server-data: + driver: local + ambari-server-logs: + driver: local + ambari-server-conf: + driver: local + + # Ambari Agent + ambari-agent-data: + driver: local + ambari-agent-logs: + driver: local + ambari-agent-conf: + driver: local + + # Ambari Metrics + ambari-metrics-data: + driver: local + ambari-metrics-logs: + driver: local + ambari-metrics-conf: + driver: local + + # Grafana + grafana-data: + driver: local + + # Hadoop + namenode-data: + driver: local + datanode-data: + driver: local diff --git a/docker/images/ambari-base/Dockerfile b/docker/images/ambari-base/Dockerfile new file mode 100644 index 00000000000..42f4d6e7578 --- /dev/null +++ b/docker/images/ambari-base/Dockerfile @@ -0,0 +1,249 @@ +# Apache Ambari Base Image +# Multi-stage build for optimized production image + +ARG UBUNTU_VERSION=22.04 +FROM ubuntu:${UBUNTU_VERSION} AS base + +# Metadata +LABEL maintainer="Apache Ambari Community " +LABEL org.apache.ambari.version="3.0.0-SNAPSHOT" +LABEL org.apache.ambari.component="base" +LABEL org.opencontainers.image.source="https://github.com/apache/ambari" +LABEL org.opencontainers.image.description="Apache Ambari Base Runtime Image" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +# Build arguments +ARG JAVA_VERSION=11 +ARG MAVEN_VERSION=3.9.6 +ARG NODE_VERSION=18 +ARG PYTHON_VERSION=3.10 + +# Environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=UTC +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 + +# Create ambari user and group +RUN groupadd -r ambari --gid=1000 && \ + useradd -r -g ambari --uid=1000 --home-dir=/opt/ambari --shell=/bin/bash ambari && \ + mkdir -p /opt/ambari && \ + chown -R ambari:ambari /opt/ambari + +# Install system dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + # Basic utilities + curl \ + wget \ + unzip \ + zip \ + tar \ + gzip \ + ca-certificates \ + gnupg \ + lsb-release \ + # Network tools + net-tools \ + netcat \ + telnet \ + openssh-client \ + # System tools + sudo \ + vim \ + less \ + htop \ + procps \ + psmisc \ + # Build tools (for native dependencies) + build-essential \ + gcc \ + g++ \ + make \ + # Python and pip + python3 \ + python3-pip \ + python3-dev \ + python3-setuptools \ + python3-wheel \ + # Git for source management + git \ + # Database clients + postgresql-client \ + mysql-client \ + # SSL/TLS support + openssl \ + # Time synchronization + ntp \ + ntpdate \ + # Process management + supervisor && \ + # Clean up + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Install OpenJDK +RUN apt-get update && \ + apt-get install -y --no-install-recommends openjdk-${JAVA_VERSION}-jdk && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Set JAVA_HOME +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV PATH=${JAVA_HOME}/bin:${PATH} + +# Install Maven using apt package manager (more reliable) +RUN apt-get update && \ + apt-get install -y --no-install-recommends maven && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Set Maven environment (Ubuntu package installs to /usr/share/maven) +ENV MAVEN_HOME=/usr/share/maven +ENV PATH=${MAVEN_HOME}/bin:${PATH} + +# Install Node.js and npm using apt package manager (more reliable) +RUN apt-get update && \ + apt-get install -y --no-install-recommends nodejs npm && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install Python packages +RUN pip3 install --no-cache-dir \ + setuptools \ + wheel \ + requests \ + pyyaml \ + jinja2 \ + psutil \ + six + +# Create directory structure +RUN mkdir -p \ + /var/log/ambari-server \ + /var/log/ambari-agent \ + /var/log/ambari-metrics-collector \ + /var/log/ambari-metrics-monitor \ + /var/run/ambari-server \ + /var/run/ambari-agent \ + /var/run/ambari-metrics-collector \ + /var/run/ambari-metrics-monitor \ + /var/lib/ambari-server \ + /var/lib/ambari-agent \ + /var/lib/ambari-metrics-collector \ + /etc/ambari-server/conf \ + /etc/ambari-agent/conf \ + /etc/ambari-metrics-collector/conf \ + /etc/ambari-metrics-monitor/conf && \ + chown -R ambari:ambari \ + /var/log/ambari-* \ + /var/run/ambari-* \ + /var/lib/ambari-* \ + /etc/ambari-* + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \ + chmod 0440 /etc/sudoers.d/ambari + +# SSH configuration for multi-node setups +RUN mkdir -p /home/ambari/.ssh && \ + ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \ + cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \ + chmod 600 /home/ambari/.ssh/authorized_keys && \ + chmod 700 /home/ambari/.ssh && \ + chown -R ambari:ambari /home/ambari/.ssh + +# Configure SSH daemon +RUN apt-get update && apt-get install -y openssh-server && \ + mkdir -p /var/run/sshd && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \ + sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config + +# Set up Maven repository cache +RUN mkdir -p /home/ambari/.m2 && \ + chown -R ambari:ambari /home/ambari/.m2 + +# Health check script +COPY scripts/health-check.sh /usr/local/bin/health-check.sh +RUN chmod +x /usr/local/bin/health-check.sh + +# Entrypoint script +COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +# Set working directory +WORKDIR /opt/ambari + +# Switch to ambari user +USER ambari + +# Default command +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["bash"] + +# Build stage for development +FROM base AS build + +# Switch back to root for build tools +USER root + +# Install additional build dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + # Additional build tools + cmake \ + autoconf \ + automake \ + libtool \ + pkg-config \ + # Development headers + libssl-dev \ + libffi-dev \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + # RPM building tools + rpm \ + rpmbuild \ + # Debugging tools + gdb \ + strace \ + tcpdump && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install additional Python development packages +RUN pip3 install --no-cache-dir \ + pytest \ + mock \ + coverage \ + flake8 \ + pylint + +# Pre-download Maven dependencies for faster builds +COPY pom.xml /tmp/pom.xml +RUN cd /tmp && \ + mvn dependency:go-offline -B -q && \ + rm -rf /tmp/* + +# Switch back to ambari user +USER ambari + +# Runtime stage for production +FROM base AS runtime + +# Copy only necessary files from build stage +# This keeps the runtime image smaller + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Expose common ports +EXPOSE 8080 8441 8440 6188 61888 + +# Default volumes +VOLUME ["/var/log/ambari-server", "/var/log/ambari-agent", "/var/log/ambari-metrics-collector"] +VOLUME ["/var/lib/ambari-server", "/var/lib/ambari-agent", "/var/lib/ambari-metrics-collector"] +VOLUME ["/etc/ambari-server/conf", "/etc/ambari-agent/conf", "/etc/ambari-metrics-collector/conf"] diff --git a/docker/images/ambari-base/docker-build.sh b/docker/images/ambari-base/docker-build.sh new file mode 100755 index 00000000000..acac7a1e334 --- /dev/null +++ b/docker/images/ambari-base/docker-build.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Base Image Build Script + +set -e + +# Default configuration +DEFAULT_DOCKER_TAG="ambari-base:latest" +DEFAULT_OPENJDK_IMAGE="openjdk" +DEFAULT_JDK_VERSION="8" + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Base Image Build Script + +Usage: $0 [Docker Tag] [JDK Version] [OpenJDK Image] + +Parameters: + Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'. + JDK Version The JDK version to use. Default is '$DEFAULT_JDK_VERSION' + OpenJDK Image Base image to use. Default is '$DEFAULT_OPENJDK_IMAGE'. + +Examples: + $0 ambari-base:latest + $0 ambari-base:8 8 openjdk + $0 ambari-base:arm64 8 arm64v8/openjdk + +EOF +} + +# Parse arguments +DOCKER_TAG="${1:-$DEFAULT_DOCKER_TAG}" +JDK_VERSION="${2:-$DEFAULT_JDK_VERSION}" +OPENJDK_IMAGE="${3:-$DEFAULT_OPENJDK_IMAGE}" + +if [[ "$1" == "--help" || "$1" == "-h" ]]; then + show_usage + exit 0 +fi + +log_info "Building Ambari Base Image" +log_info "Docker Tag: $DOCKER_TAG" +log_info "JDK Version: $JDK_VERSION" +log_info "OpenJDK Image: $OPENJDK_IMAGE" + +# Build the image from docker root directory to access scripts +DOCKER_ROOT="$SCRIPT_DIR/../../" +docker build \ + --build-arg JDK_VERSION="$JDK_VERSION" \ + --build-arg OPENJDK_IMAGE="$OPENJDK_IMAGE" \ + -t "$DOCKER_TAG" \ + -f "$SCRIPT_DIR/Dockerfile" \ + "$DOCKER_ROOT" + +log_info "Successfully built: $DOCKER_TAG" diff --git a/docker/images/ambari-metrics/Dockerfile b/docker/images/ambari-metrics/Dockerfile new file mode 100644 index 00000000000..847aec93912 --- /dev/null +++ b/docker/images/ambari-metrics/Dockerfile @@ -0,0 +1,181 @@ +# Multi-stage Dockerfile for Apache Ambari Metrics Collector +# Based on best practices from Apache Pinot and other Apache projects + +# Build stage +FROM ubuntu:22.04 AS builder + +# Build arguments +ARG MAVEN_VERSION=3.9.6 +ARG JAVA_VERSION=11 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV MAVEN_HOME=/opt/maven +ENV PATH=$PATH:$MAVEN_HOME/bin + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jdk \ + maven \ + curl \ + wget \ + git \ + build-essential \ + python3 \ + python3-pip \ + python3-dev \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /workspace + +# Copy source code +COPY . . + +# Build Ambari Metrics +RUN mvn clean install -pl ambari-metrics -DskipTests -Drat.skip=true \ + && mvn clean package -pl ambari-metrics/ambari-metrics-assembly -DskipTests + +# Runtime stage +FROM ubuntu:22.04 AS runtime + +# Runtime arguments +ARG JAVA_VERSION=11 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV AMBARI_METRICS_HOME=/opt/ambari-metrics +ENV PATH=$PATH:$AMBARI_METRICS_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jre-headless \ + python3 \ + python3-pip \ + curl \ + wget \ + netcat \ + procps \ + net-tools \ + && rm -rf /var/lib/apt/lists/* + +# Copy built artifacts from builder stage +COPY --from=builder /workspace/ambari-metrics/ambari-metrics-assembly/target/ambari-metrics-assembly-*.tar.gz /tmp/ + +# Install Ambari Metrics +RUN cd /tmp && \ + tar -xzf ambari-metrics-assembly-*.tar.gz && \ + mv ambari-metrics-assembly-* /opt/ambari-metrics && \ + rm -f /tmp/*.tar.gz + +# Create necessary directories +RUN mkdir -p /var/lib/ambari-metrics-collector \ + /var/log/ambari-metrics-collector \ + /etc/ambari-metrics-collector/conf \ + && chown -R ambari:ambari /var/lib/ambari-metrics-collector \ + /var/log/ambari-metrics-collector \ + /etc/ambari-metrics-collector \ + /opt/ambari-metrics + +# Copy configuration files and scripts +COPY docker/config/metrics/ /etc/ambari-metrics-collector/conf/ +COPY docker/scripts/ /usr/local/bin/ + +# Make scripts executable +RUN chmod +x /usr/local/bin/*.sh + +# Create startup script +RUN cat > /usr/local/bin/start-ambari-metrics.sh << 'EOF' +#!/bin/bash +set -e + +# Configure metrics collector +echo "Configuring Ambari Metrics Collector..." + +# Set heap size +export COLLECTOR_HEAPSIZE=${METRICS_COLLECTOR_HEAPSIZE:-1024m} + +# Create HBase configuration +mkdir -p /var/lib/ambari-metrics-collector/hbase/conf + +# Configure HBase for embedded mode +cat > /var/lib/ambari-metrics-collector/hbase/conf/hbase-site.xml << EOL + + + + hbase.rootdir + file:///var/lib/ambari-metrics-collector/hbase + + + hbase.zookeeper.property.dataDir + /var/lib/ambari-metrics-collector/hbase/zookeeper + + + hbase.cluster.distributed + false + + + hbase.tmp.dir + /var/lib/ambari-metrics-collector/hbase/tmp + + +EOL + +# Start Ambari Metrics Collector +echo "Starting Ambari Metrics Collector..." +cd /opt/ambari-metrics +exec ./bin/ambari-metrics-collector start +EOF + +RUN chmod +x /usr/local/bin/start-ambari-metrics.sh + +# Switch to ambari user +USER ambari + +# Expose metrics ports +EXPOSE 6188 61888 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ + CMD /usr/local/bin/health-check.sh metrics + +# Set working directory +WORKDIR /home/ambari + +# Default command +CMD ["/usr/local/bin/start-ambari-metrics.sh"] + +# Development stage +FROM runtime AS development + +# Switch back to root for development tools +USER root + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + maven \ + git \ + vim \ + less \ + htop \ + && rm -rf /var/lib/apt/lists/* + +# Create Maven cache directory +RUN mkdir -p /home/ambari/.m2 && \ + chown -R ambari:ambari /home/ambari/.m2 + +# Switch back to ambari user +USER ambari + +# Mount point for source code +VOLUME ["/workspace"] + +# Default command for development +CMD ["bash"] diff --git a/docker/images/ambari-metrics/docker-build.sh b/docker/images/ambari-metrics/docker-build.sh new file mode 100755 index 00000000000..11b970330f5 --- /dev/null +++ b/docker/images/ambari-metrics/docker-build.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Metrics Image Build Script + +set -e + +# Default configuration +DEFAULT_DOCKER_TAG="ambari-metrics:latest" +DEFAULT_BASE_IMAGE="ambari-base:latest" + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Metrics Image Build Script + +Usage: $0 [Docker Tag] [Base Image] + +Parameters: + Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'. + Base Image Base image to use. Default is '$DEFAULT_BASE_IMAGE'. + +Examples: + $0 ambari-metrics:latest + $0 ambari-metrics:2.7.5 ambari-base:2.7.5 + +EOF +} + +# Parse arguments +DOCKER_TAG="${1:-$DEFAULT_DOCKER_TAG}" +BASE_IMAGE="${2:-$DEFAULT_BASE_IMAGE}" + +if [[ "$1" == "--help" || "$1" == "-h" ]]; then + show_usage + exit 0 +fi + +log_info "Building Ambari Metrics Image" +log_info "Docker Tag: $DOCKER_TAG" +log_info "Base Image: $BASE_IMAGE" + +# Build the image +docker build \ + --build-arg BASE_IMAGE="$BASE_IMAGE" \ + -t "$DOCKER_TAG" \ + -f "$SCRIPT_DIR/Dockerfile" \ + "$SCRIPT_DIR" + +log_info "Successfully built: $DOCKER_TAG" diff --git a/docker/images/ambari/Dockerfile b/docker/images/ambari/Dockerfile new file mode 100644 index 00000000000..b91f37bd3fd --- /dev/null +++ b/docker/images/ambari/Dockerfile @@ -0,0 +1,172 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Multi-stage Dockerfile for Apache Ambari +# Based on Apache Pinot's Docker approach + +ARG OPENJDK_IMAGE=eclipse-temurin +ARG JDK_VERSION=8 +ARG UBUNTU_VERSION=20.04 + +# Build stage +FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jdk AS builder + +# Build arguments +ARG AMBARI_GIT_URL=https://github.com/apache/ambari.git +ARG AMBARI_BRANCH=trunk +ARG MAVEN_VERSION=3.6.3 +ARG NODE_VERSION=14 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION} +ENV MAVEN_HOME=/opt/maven +ENV NODE_HOME=/opt/node +ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + curl \ + wget \ + git \ + build-essential \ + python3 \ + python3-pip \ + python3-dev \ + rpm \ + alien \ + && rm -rf /var/lib/apt/lists/* + +# Install Maven +RUN wget -q https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ + && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt \ + && mv /opt/apache-maven-${MAVEN_VERSION} /opt/maven \ + && rm apache-maven-${MAVEN_VERSION}-bin.tar.gz + +# Install Node.js +RUN wget -q https://nodejs.org/dist/v${NODE_VERSION}.20.1/node-v${NODE_VERSION}.20.1-linux-x64.tar.xz \ + && tar -xJf node-v${NODE_VERSION}.20.1-linux-x64.tar.xz -C /opt \ + && mv /opt/node-v${NODE_VERSION}.20.1-linux-x64 /opt/node \ + && rm node-v${NODE_VERSION}.20.1-linux-x64.tar.xz + +# Set working directory +WORKDIR /tmp/ambari-build + +# Clone and build Ambari +RUN git clone ${AMBARI_GIT_URL} . \ + && git checkout ${AMBARI_BRANCH} \ + && mvn clean install -DskipTests -Drat.skip=true -Dfindbugs.skip=true \ + && mvn clean package rpm:rpm -DskipTests -Drat.skip=true + +# Runtime stage +FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jre AS runtime + +# Runtime arguments +ARG OPENJDK_IMAGE=eclipse-temurin +ARG JDK_VERSION=8 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/opt/java/openjdk +ENV AMBARI_HOME=/opt/ambari +ENV PATH=$PATH:$AMBARI_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + python3 \ + python3-pip \ + postgresql-client \ + curl \ + wget \ + netcat-openbsd \ + procps \ + net-tools \ + sudo \ + openssh-server \ + rsync \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN pip3 install psycopg2-binary requests pyyaml + +# Copy built artifacts from builder stage +COPY --from=builder /tmp/ambari-build/ambari-server/target/rpm/ambari-server/RPMS/noarch/*.rpm /tmp/ +COPY --from=builder /tmp/ambari-build/ambari-agent/target/rpm/ambari-agent/RPMS/noarch/*.rpm /tmp/ + +# Convert and install RPM packages +RUN cd /tmp && \ + for rpm in *.rpm; do \ + alien -d --scripts "$rpm"; \ + done && \ + dpkg -i *.deb && \ + rm -f /tmp/*.rpm /tmp/*.deb + +# Create necessary directories +RUN mkdir -p /var/lib/ambari-server \ + /var/log/ambari-server \ + /var/lib/ambari-agent \ + /var/log/ambari-agent \ + /etc/ambari-server/conf \ + /etc/ambari-agent/conf \ + /opt/ambari \ + && chown -R ambari:ambari /var/lib/ambari-* \ + /var/log/ambari-* \ + /etc/ambari-* \ + /opt/ambari + +# Copy configuration files and scripts +COPY images/ambari/bin/ /opt/ambari/bin/ +COPY images/ambari/etc/ /etc/ambari/ +COPY scripts/ /usr/local/bin/ + +# Make scripts executable +RUN chmod +x /opt/ambari/bin/*.sh /usr/local/bin/*.sh + +# Configure SSH +RUN apt-get update && apt-get install -y openssh-server && \ + mkdir -p /var/run/sshd && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +# Switch to ambari user +USER ambari + +# Expose ports +EXPOSE 8080 8441 8440 6188 61888 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Set working directory +WORKDIR /home/ambari + +# Entry point +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +# Default command (Pinot-style - uses pinot-admin.sh equivalent) +CMD ["ambari-admin.sh"] diff --git a/docker/images/ambari/Dockerfile.agent b/docker/images/ambari/Dockerfile.agent new file mode 100644 index 00000000000..2d610041701 --- /dev/null +++ b/docker/images/ambari/Dockerfile.agent @@ -0,0 +1,215 @@ +# Multi-stage Dockerfile for Apache Ambari Agent +# Based on best practices from Apache Pinot and other Apache projects + +# Build stage +FROM ubuntu:22.04 AS builder + +# Build arguments +ARG MAVEN_VERSION=3.9.6 +ARG JAVA_VERSION=11 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV MAVEN_HOME=/opt/maven +ENV PATH=$PATH:$MAVEN_HOME/bin + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jdk \ + maven \ + curl \ + wget \ + git \ + build-essential \ + python3 \ + python3-pip \ + python3-dev \ + rpm \ + alien \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /workspace + +# Copy source code +COPY . . + +# Build Ambari Agent +RUN mvn clean install -pl ambari-agent -DskipTests -Drat.skip=true \ + && mvn clean package rpm:rpm -pl ambari-agent -DskipTests + +# Runtime stage +FROM ubuntu:22.04 AS runtime + +# Runtime arguments +ARG JAVA_VERSION=11 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV AMBARI_AGENT_HOME=/opt/ambari-agent +ENV PATH=$PATH:$AMBARI_AGENT_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jre-headless \ + python3 \ + python3-pip \ + curl \ + wget \ + netcat-openbsd \ + procps \ + net-tools \ + sudo \ + openssh-server \ + rsync \ + psmisc \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN pip3 install requests psutil pyyaml + +# Copy built artifacts from builder stage +COPY --from=builder /workspace/ambari-agent/target/rpm/ambari-agent/RPMS/x86_64/*.rpm /tmp/ + +# Convert and install RPM packages +RUN cd /tmp && \ + for rpm in *.rpm; do \ + alien -d --scripts "$rpm"; \ + done && \ + dpkg -i *.deb && \ + rm -f /tmp/*.rpm /tmp/*.deb + +# Create necessary directories +RUN mkdir -p /var/lib/ambari-agent \ + /var/log/ambari-agent \ + /etc/ambari-agent/conf \ + /opt/ambari-agent \ + && chown -R ambari:ambari /var/lib/ambari-agent \ + /var/log/ambari-agent \ + /etc/ambari-agent \ + /opt/ambari-agent + +# Copy configuration files and scripts +COPY docker/config/agent/ /etc/ambari-agent/conf/ +COPY docker/scripts/ /usr/local/bin/ + +# Make scripts executable +RUN chmod +x /usr/local/bin/*.sh + +# Create startup script +RUN cat > /usr/local/bin/start-ambari-agent.sh << 'EOF' +#!/bin/bash +set -e + +# Wait for Ambari Server +echo "Waiting for Ambari Server at ${AMBARI_SERVER_HOST:-ambari-server}:${AMBARI_SERVER_PORT:-8080}..." +while ! nc -z ${AMBARI_SERVER_HOST:-ambari-server} ${AMBARI_SERVER_PORT:-8080}; do + echo "Ambari Server not ready, waiting..." + sleep 10 +done +echo "Ambari Server is ready!" + +# Configure agent +echo "Configuring Ambari Agent..." +cat > /etc/ambari-agent/conf/ambari-agent.ini << EOL +[server] +hostname=${AMBARI_SERVER_HOST:-ambari-server} +url_port=${AMBARI_SERVER_PORT:-8080} +secured_url_port=8441 + +[agent] +prefix=/var/lib/ambari-agent/data +cache_dir=/var/lib/ambari-agent/cache +log_dir=/var/log/ambari-agent +pidfile=/var/run/ambari-agent/ambari-agent.pid +hostname_script=/var/lib/ambari-agent/hostname.sh + +[security] +keysdir=/var/lib/ambari-agent/keys +server_crt=ca.crt +passphrase_env_var_name=AMBARI_PASSPHRASE + +[heartbeat] +state_interval=6 +dirs=/etc/hadoop,/etc/hadoop/conf,/etc/hbase,/etc/hcatalog,/etc/hive,/etc/oozie,/etc/sqoop,/var/run/hadoop,/var/run/zookeeper,/var/run/hbase,/var/run/hive,/var/run/oozie,/var/log/hadoop,/var/log/zookeeper,/var/log/hbase,/var/log/hive,/var/log/oozie +rpms=hadoop,zookeeper,hbase,hive +EOL + +# Create hostname script +cat > /var/lib/ambari-agent/hostname.sh << 'EOL' +#!/bin/bash +echo $(hostname -f) +EOL +chmod +x /var/lib/ambari-agent/hostname.sh + +# Start SSH daemon +sudo service ssh start + +# Start Ambari Agent +echo "Starting Ambari Agent..." +exec ambari-agent start --debug=${AMBARI_DEBUG:-false} +EOF + +RUN chmod +x /usr/local/bin/start-ambari-agent.sh + +# Configure SSH +RUN apt-get update && apt-get install -y openssh-server && \ + mkdir -p /var/run/sshd && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +# Switch to ambari user +USER ambari + +# Expose SSH port +EXPOSE 22 5006 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD /usr/local/bin/health-check.sh agent + +# Set working directory +WORKDIR /home/ambari + +# Default command +CMD ["/usr/local/bin/start-ambari-agent.sh"] + +# Development stage +FROM runtime AS development + +# Switch back to root for development tools +USER root + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + maven \ + git \ + vim \ + less \ + htop \ + strace \ + tcpdump \ + && rm -rf /var/lib/apt/lists/* + +# Create Maven cache directory +RUN mkdir -p /home/ambari/.m2 && \ + chown -R ambari:ambari /home/ambari/.m2 + +# Switch back to ambari user +USER ambari + +# Mount point for source code +VOLUME ["/workspace"] + +# Default command for development +CMD ["bash"] diff --git a/docker/images/ambari/Dockerfile.build b/docker/images/ambari/Dockerfile.build new file mode 100644 index 00000000000..c4291590592 --- /dev/null +++ b/docker/images/ambari/Dockerfile.build @@ -0,0 +1,186 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Build-only Dockerfile for Apache Ambari +# This image is used for building Ambari from source + +ARG OPENJDK_IMAGE=openjdk +ARG JDK_VERSION=8 +ARG UBUNTU_VERSION=20.04 + +FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jdk-slim + +# Build arguments +ARG MAVEN_VERSION=3.6.3 +ARG NODE_VERSION=14 +ARG PYTHON_VERSION=3.8 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION} +ENV MAVEN_HOME=/opt/maven +ENV NODE_HOME=/opt/node +ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + # Basic utilities + curl \ + wget \ + unzip \ + zip \ + tar \ + gzip \ + ca-certificates \ + gnupg \ + lsb-release \ + # Build tools + build-essential \ + gcc \ + g++ \ + make \ + cmake \ + autoconf \ + automake \ + libtool \ + pkg-config \ + # Version control + git \ + # Python and development tools + python3 \ + python3-pip \ + python3-dev \ + python3-setuptools \ + python3-wheel \ + # RPM building tools + rpm \ + rpmbuild \ + alien \ + # Development headers + libssl-dev \ + libffi-dev \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + # Network tools + net-tools \ + netcat-openbsd \ + telnet \ + openssh-client \ + # System tools + sudo \ + vim \ + less \ + htop \ + procps \ + psmisc \ + # Debugging tools + gdb \ + strace \ + tcpdump \ + && rm -rf /var/lib/apt/lists/* + +# Install Maven +RUN wget -q https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ + && tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt \ + && mv /opt/apache-maven-${MAVEN_VERSION} /opt/maven \ + && rm apache-maven-${MAVEN_VERSION}-bin.tar.gz + +# Install Node.js and npm +RUN wget -q https://nodejs.org/dist/v${NODE_VERSION}.20.1/node-v${NODE_VERSION}.20.1-linux-x64.tar.xz \ + && tar -xJf node-v${NODE_VERSION}.20.1-linux-x64.tar.xz -C /opt \ + && mv /opt/node-v${NODE_VERSION}.20.1-linux-x64 /opt/node \ + && rm node-v${NODE_VERSION}.20.1-linux-x64.tar.xz + +# Install global npm packages +RUN npm install -g brunch bower grunt-cli + +# Install Python development packages +RUN pip3 install --no-cache-dir \ + setuptools \ + wheel \ + requests \ + pyyaml \ + jinja2 \ + psutil \ + six \ + pytest \ + mock \ + coverage \ + flake8 \ + pylint + +# Create directory structure +RUN mkdir -p \ + /var/log/ambari-server \ + /var/log/ambari-agent \ + /var/log/ambari-metrics-collector \ + /var/run/ambari-server \ + /var/run/ambari-agent \ + /var/run/ambari-metrics-collector \ + /var/lib/ambari-server \ + /var/lib/ambari-agent \ + /var/lib/ambari-metrics-collector \ + /etc/ambari-server/conf \ + /etc/ambari-agent/conf \ + /etc/ambari-metrics-collector/conf \ + /home/ambari/.m2 \ + /workspace \ + && chown -R ambari:ambari \ + /var/log/ambari-* \ + /var/run/ambari-* \ + /var/lib/ambari-* \ + /etc/ambari-* \ + /home/ambari \ + /workspace + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \ + chmod 0440 /etc/sudoers.d/ambari + +# SSH configuration for multi-node setups +RUN mkdir -p /home/ambari/.ssh && \ + ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \ + cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \ + chmod 600 /home/ambari/.ssh/authorized_keys && \ + chmod 700 /home/ambari/.ssh && \ + chown -R ambari:ambari /home/ambari/.ssh + +# Pre-download Maven dependencies for faster builds +COPY pom.xml /tmp/pom.xml +RUN cd /tmp && \ + mvn dependency:go-offline -B -q || true && \ + rm -rf /tmp/* + +# Switch to ambari user +USER ambari + +# Set working directory +WORKDIR /workspace + +# Default volumes +VOLUME ["/workspace", "/home/ambari/.m2"] + +# Default command +CMD ["bash"] diff --git a/docker/images/ambari/Dockerfile.package b/docker/images/ambari/Dockerfile.package new file mode 100644 index 00000000000..4728dff02ab --- /dev/null +++ b/docker/images/ambari/Dockerfile.package @@ -0,0 +1,168 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Package-based Dockerfile for Apache Ambari +# This image uses pre-built packages instead of building from source + +ARG OPENJDK_IMAGE=openjdk +ARG JDK_VERSION=8 +ARG UBUNTU_VERSION=20.04 + +FROM ${OPENJDK_IMAGE}:${JDK_VERSION}-jre-slim + +# Build arguments +ARG AMBARI_VERSION=2.7.5 +ARG AMBARI_REPO_URL=http://public-repo-1.hortonworks.com/ambari/ubuntu18/2.x/updates/2.7.5.0 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/local/openjdk-${JDK_VERSION} +ENV AMBARI_HOME=/opt/ambari +ENV PATH=$PATH:$AMBARI_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + # Basic utilities + curl \ + wget \ + unzip \ + zip \ + tar \ + gzip \ + ca-certificates \ + gnupg \ + lsb-release \ + # Python runtime + python3 \ + python3-pip \ + # Database clients + postgresql-client \ + mysql-client \ + # Network tools + net-tools \ + netcat-openbsd \ + telnet \ + openssh-client \ + openssh-server \ + # System tools + sudo \ + vim \ + less \ + htop \ + procps \ + psmisc \ + rsync \ + # SSL/TLS support + openssl \ + # Time synchronization + ntp \ + ntpdate \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN pip3 install --no-cache-dir \ + psycopg2-binary \ + requests \ + pyyaml \ + jinja2 \ + psutil \ + six + +# Add Ambari repository and install packages +RUN wget -O - ${AMBARI_REPO_URL}/RPM-GPG-KEY/RPM-GPG-KEY-Jenkins | apt-key add - && \ + echo "deb ${AMBARI_REPO_URL} Ambari main" > /etc/apt/sources.list.d/ambari.list && \ + apt-get update && \ + apt-get install -y \ + ambari-server \ + ambari-agent \ + && rm -rf /var/lib/apt/lists/* + +# Create necessary directories +RUN mkdir -p \ + /var/lib/ambari-server \ + /var/log/ambari-server \ + /var/lib/ambari-agent \ + /var/log/ambari-agent \ + /var/lib/ambari-metrics-collector \ + /var/log/ambari-metrics-collector \ + /etc/ambari-server/conf \ + /etc/ambari-agent/conf \ + /etc/ambari-metrics-collector/conf \ + /opt/ambari \ + && chown -R ambari:ambari \ + /var/lib/ambari-* \ + /var/log/ambari-* \ + /etc/ambari-* \ + /opt/ambari + +# Copy configuration files and scripts +COPY bin/ /opt/ambari/bin/ +COPY etc/ /etc/ambari/ +COPY docker/scripts/ /usr/local/bin/ + +# Make scripts executable +RUN chmod +x /opt/ambari/bin/*.sh /usr/local/bin/*.sh + +# Configure SSH +RUN apt-get update && apt-get install -y openssh-server && \ + mkdir -p /var/run/sshd && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \ + sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config + +# SSH configuration for multi-node setups +RUN mkdir -p /home/ambari/.ssh && \ + ssh-keygen -t rsa -N '' -f /home/ambari/.ssh/id_rsa && \ + cat /home/ambari/.ssh/id_rsa.pub >> /home/ambari/.ssh/authorized_keys && \ + chmod 600 /home/ambari/.ssh/authorized_keys && \ + chmod 700 /home/ambari/.ssh && \ + chown -R ambari:ambari /home/ambari/.ssh + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ambari && \ + chmod 0440 /etc/sudoers.d/ambari + +# Switch to ambari user +USER ambari + +# Expose ports +EXPOSE 8080 8441 8440 6188 61888 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \ + CMD /usr/local/bin/health-check.sh + +# Set working directory +WORKDIR /home/ambari + +# Default volumes +VOLUME ["/var/log/ambari-server", "/var/log/ambari-agent", "/var/log/ambari-metrics-collector"] +VOLUME ["/var/lib/ambari-server", "/var/lib/ambari-agent", "/var/lib/ambari-metrics-collector"] +VOLUME ["/etc/ambari-server/conf", "/etc/ambari-agent/conf", "/etc/ambari-metrics-collector/conf"] + +# Entry point +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +# Default command +CMD ["ambari-admin.sh"] diff --git a/docker/images/ambari/Dockerfile.server b/docker/images/ambari/Dockerfile.server new file mode 100644 index 00000000000..e9f178b62b4 --- /dev/null +++ b/docker/images/ambari/Dockerfile.server @@ -0,0 +1,202 @@ +# Multi-stage Dockerfile for Apache Ambari Server +# Based on best practices from Apache Pinot and other Apache projects + +# Build stage +FROM ubuntu:22.04 AS builder + +# Build arguments +ARG MAVEN_VERSION=3.9.6 +ARG JAVA_VERSION=11 +ARG NODE_VERSION=18 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV MAVEN_HOME=/opt/maven +ENV NODE_HOME=/opt/node +ENV PATH=$PATH:$MAVEN_HOME/bin:$NODE_HOME/bin + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jdk \ + maven \ + nodejs \ + npm \ + curl \ + wget \ + git \ + build-essential \ + python3 \ + python3-pip \ + python3-dev \ + rpm \ + alien \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /workspace + +# Copy source code +COPY . . + +# Build Ambari Server +RUN mvn clean install -DskipTests -Drat.skip=true -Dfindbugs.skip=true \ + && mvn clean package rpm:rpm -pl ambari-server -DskipTests -Drat.skip=true + +# Runtime stage +FROM ubuntu:22.04 AS runtime + +# Runtime arguments +ARG JAVA_VERSION=11 + +# Set environment variables +ENV DEBIAN_FRONTEND=noninteractive +ENV JAVA_HOME=/usr/lib/jvm/java-${JAVA_VERSION}-openjdk-amd64 +ENV AMBARI_HOME=/opt/ambari +ENV AMBARI_SERVER_HOME=/opt/ambari-server +ENV PATH=$PATH:$AMBARI_SERVER_HOME/bin + +# Create ambari user +RUN groupadd -r ambari && useradd -r -g ambari -d /home/ambari -s /bin/bash ambari \ + && mkdir -p /home/ambari \ + && chown -R ambari:ambari /home/ambari + +# Install runtime dependencies +RUN apt-get update && apt-get install -y \ + openjdk-${JAVA_VERSION}-jre-headless \ + python3 \ + python3-pip \ + postgresql-client \ + curl \ + wget \ + netcat-openbsd \ + procps \ + net-tools \ + sudo \ + openssh-server \ + rsync \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN pip3 install psycopg2-binary requests pyyaml + +# Copy built artifacts from builder stage +COPY --from=builder /workspace/ambari-server/target/rpm/ambari-server/RPMS/noarch/*.rpm /tmp/ + +# Convert and install RPM packages +RUN cd /tmp && \ + for rpm in *.rpm; do \ + alien -d --scripts "$rpm"; \ + done && \ + dpkg -i *.deb && \ + rm -f /tmp/*.rpm /tmp/*.deb + +# Create necessary directories +RUN mkdir -p /var/lib/ambari-server \ + /var/log/ambari-server \ + /etc/ambari-server/conf \ + /opt/ambari-server \ + && chown -R ambari:ambari /var/lib/ambari-server \ + /var/log/ambari-server \ + /etc/ambari-server \ + /opt/ambari-server + +# Copy configuration files and scripts +COPY docker/config/server/ /etc/ambari-server/conf/ +COPY docker/scripts/ /usr/local/bin/ + +# Make scripts executable +RUN chmod +x /usr/local/bin/*.sh + +# Create startup script +RUN cat > /usr/local/bin/start-ambari-server.sh << 'EOF' +#!/bin/bash +set -e + +# Wait for database +echo "Waiting for database connection..." +while ! nc -z ${AMBARI_DB_HOST:-localhost} ${AMBARI_DB_PORT:-5432}; do + echo "Database not ready, waiting..." + sleep 5 +done +echo "Database is ready!" + +# Setup database if not already done +if [ ! -f /var/lib/ambari-server/.db-setup-done ]; then + echo "Setting up Ambari database..." + ambari-server setup --database=postgres \ + --databasehost=${AMBARI_DB_HOST:-localhost} \ + --databaseport=${AMBARI_DB_PORT:-5432} \ + --databasename=${AMBARI_DB_NAME:-ambari} \ + --databaseusername=${AMBARI_DB_USER:-ambari} \ + --databasepassword=${AMBARI_DB_PASSWORD:-bigdata} \ + --silent + + touch /var/lib/ambari-server/.db-setup-done + echo "Database setup completed!" +fi + +# Start Ambari Server +echo "Starting Ambari Server..." +exec ambari-server start --debug=${AMBARI_DEBUG:-false} +EOF + +RUN chmod +x /usr/local/bin/start-ambari-server.sh + +# Configure SSH +RUN apt-get update && apt-get install -y openssh-server && \ + mkdir -p /var/run/sshd && \ + sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config + +# Configure sudo for ambari user +RUN echo "ambari ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +# Switch to ambari user +USER ambari + +# Expose ports +EXPOSE 8080 8441 5005 + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \ + CMD /usr/local/bin/health-check.sh server + +# Set working directory +WORKDIR /home/ambari + +# Default command +CMD ["/usr/local/bin/start-ambari-server.sh"] + +# Development stage +FROM runtime AS development + +# Switch back to root for development tools +USER root + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + maven \ + nodejs \ + npm \ + git \ + vim \ + less \ + htop \ + && rm -rf /var/lib/apt/lists/* + +# Install global npm packages +RUN npm install -g brunch + +# Create Maven cache directory +RUN mkdir -p /home/ambari/.m2 && \ + chown -R ambari:ambari /home/ambari/.m2 + +# Switch back to ambari user +USER ambari + +# Mount point for source code +VOLUME ["/workspace"] + +# Default command for development +CMD ["bash"] diff --git a/docker/images/ambari/QUICKSTART.md b/docker/images/ambari/QUICKSTART.md new file mode 100644 index 00000000000..861790bafc3 --- /dev/null +++ b/docker/images/ambari/QUICKSTART.md @@ -0,0 +1,343 @@ +# Apache Ambari Docker Quick Start Guide + +This guide will help you quickly set up and run Apache Ambari using Docker for development and testing purposes. + +## Prerequisites + +- Docker 20.10+ installed and running +- Docker Compose 2.0+ installed +- At least 8GB RAM available for Docker +- At least 20GB free disk space + +## Quick Setup (5 minutes) + +### 1. Clone and Navigate +```bash +git clone https://github.com/apache/ambari.git +cd ambari +``` + +### 2. Start Development Environment +```bash +# Start all services +docker-compose -f docker/docker-compose.dev.yml up -d + +# Check status +docker-compose -f docker/docker-compose.dev.yml ps +``` + +### 3. Access Services +- **Ambari Web UI**: http://localhost:8080 (admin/admin) +- **Grafana Dashboard**: http://localhost:3000 (admin/admin) +- **Database**: localhost:5432 (ambari/bigdata) + +### 4. Build Ambari (Optional) +```bash +# Enter development container +docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash + +# Build Ambari +cd /workspace +mvn clean install -DskipTests + +# Or use the build script +./docker/build.sh all +``` + +## Step-by-Step Setup + +### Step 1: Environment Check +```bash +# Check Docker version +docker --version +docker-compose --version + +# Check available resources +docker system df +docker system info | grep -E "CPUs|Total Memory" +``` + +### Step 2: Build Base Images (Optional) +```bash +# Build all images from source +./docker/build.sh all + +# Or build specific images +./docker/build.sh base +./docker/build.sh server +./docker/build.sh agent +./docker/build.sh metrics +``` + +### Step 3: Start Services +```bash +# Start database first +docker-compose -f docker/docker-compose.dev.yml up -d ambari-db + +# Wait for database to be ready +docker-compose -f docker/docker-compose.dev.yml logs -f ambari-db + +# Start all services +docker-compose -f docker/docker-compose.dev.yml up -d + +# Monitor startup +docker-compose -f docker/docker-compose.dev.yml logs -f +``` + +### Step 4: Verify Installation +```bash +# Check service health +docker-compose -f docker/docker-compose.dev.yml ps + +# Check Ambari Server logs +docker-compose -f docker/docker-compose.dev.yml logs ambari-server + +# Test API endpoint +curl -u admin:admin http://localhost:8080/api/v1/clusters +``` + +## Development Workflow + +### Building and Testing +```bash +# Enter development container +docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash + +# Navigate to workspace +cd /workspace + +# Build specific module +mvn clean install -pl ambari-server -DskipTests + +# Run tests +mvn test -pl ambari-server + +# Build RPMs +mvn clean package rpm:rpm -DskipTests +``` + +### Live Development +```bash +# Source code is mounted at /workspace +# Changes are reflected immediately + +# Restart services after code changes +docker-compose -f docker/docker-compose.dev.yml restart ambari-server + +# View logs +docker-compose -f docker/docker-compose.dev.yml logs -f ambari-server +``` + +### Debugging +```bash +# Enable debug mode +export AMBARI_DEBUG=true +docker-compose -f docker/docker-compose.dev.yml up -d + +# Connect debugger to: +# - Server: localhost:5005 +# - Agent: localhost:5006 + +# Access container shell +docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash +``` + +## Common Tasks + +### Scale Agents +```bash +# Scale to 3 agents +docker-compose -f docker/docker-compose.dev.yml up -d --scale ambari-agent=3 + +# Check agent status +docker-compose -f docker/docker-compose.dev.yml ps ambari-agent +``` + +### Database Operations +```bash +# Connect to database +docker-compose -f docker/docker-compose.dev.yml exec ambari-db psql -U ambari -d ambari + +# Backup database +docker-compose -f docker/docker-compose.dev.yml exec ambari-db pg_dump -U ambari ambari > backup.sql + +# Restore database +docker-compose -f docker/docker-compose.dev.yml exec -T ambari-db psql -U ambari -d ambari < backup.sql +``` + +### View Metrics +```bash +# Access Grafana +open http://localhost:3000 + +# Check metrics API +curl http://localhost:6188/ws/v1/timeline/metrics/metadata + +# View metrics logs +docker-compose -f docker/docker-compose.dev.yml logs ambari-metrics +``` + +### Clean Up +```bash +# Stop all services +docker-compose -f docker/docker-compose.dev.yml down + +# Remove volumes (WARNING: This deletes all data) +docker-compose -f docker/docker-compose.dev.yml down -v + +# Clean up images +docker system prune -a +``` + +## Troubleshooting + +### Common Issues + +#### Services Won't Start +```bash +# Check logs +docker-compose -f docker/docker-compose.dev.yml logs + +# Check resource usage +docker stats + +# Restart specific service +docker-compose -f docker/docker-compose.dev.yml restart ambari-server +``` + +#### Database Connection Issues +```bash +# Check database status +docker-compose -f docker/docker-compose.dev.yml exec ambari-db pg_isready -U ambari + +# Reset database +docker-compose -f docker/docker-compose.dev.yml down +docker volume rm ambari_ambari-db-data +docker-compose -f docker/docker-compose.dev.yml up -d ambari-db +``` + +#### Port Conflicts +```bash +# Check what's using ports +lsof -i :8080 +lsof -i :5432 + +# Change ports in docker-compose.dev.yml +# Example: "8081:8080" instead of "8080:8080" +``` + +#### Memory Issues +```bash +# Check Docker memory limit +docker system info | grep Memory + +# Increase Docker memory in Docker Desktop settings +# Or reduce JVM heap sizes in docker-compose.dev.yml +``` + +### Health Checks +```bash +# Manual health check +docker-compose -f docker/docker-compose.dev.yml exec ambari-server /usr/local/bin/health-check.sh + +# Check all container health +docker-compose -f docker/docker-compose.dev.yml ps +``` + +### Performance Tuning +```bash +# Enable BuildKit for faster builds +export DOCKER_BUILDKIT=1 + +# Use cached Maven dependencies +# (Already configured in docker-compose.dev.yml) + +# Increase JVM memory if needed +# Edit JAVA_OPTS in docker-compose.dev.yml +``` + +## Advanced Usage + +### Custom Configuration +```bash +# Create custom configuration +mkdir -p docker/config/server +echo "server.jdbc.url=jdbc:postgresql://custom-db:5432/ambari" > docker/config/server/ambari.properties + +# Mount custom config +# Add to docker-compose.dev.yml volumes: +# - ./docker/config/server:/etc/ambari-server/conf +``` + +### Multi-Node Setup +```bash +# Scale agents +docker-compose -f docker/docker-compose.dev.yml up -d --scale ambari-agent=3 + +# Each agent gets a unique hostname +# Check with: docker-compose -f docker/docker-compose.dev.yml ps +``` + +### Production-Like Setup +```bash +# Use production compose file +docker-compose -f docker/docker-compose.prod.yml up -d + +# Enable HTTPS +# Set AMBARI_SERVER_HTTPS=true in environment +``` + +### Integration with IDEs + +#### IntelliJ IDEA +1. Open project in IntelliJ +2. Configure remote debugger: + - Host: localhost + - Port: 5005 (server) or 5006 (agent) +3. Set breakpoints and start debugging + +#### VS Code +1. Install Docker extension +2. Use "Attach to Container" feature +3. Configure remote debugging in launch.json + +## Next Steps + +- Read the full [Docker README](README.md) for detailed configuration options +- Check out [Production Deployment Guide](docker-compose.prod.yml) for production setup +- Explore [Kubernetes deployment](k8s/) for container orchestration +- Join the [Ambari community](https://ambari.apache.org/mail-lists.html) for support + +## Getting Help + +- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/) +- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues) +- **Community**: [Mailing Lists](https://ambari.apache.org/mail-lists.html) +- **Docker Logs**: `docker-compose -f docker/docker-compose.dev.yml logs` + +## Useful Commands Reference + +```bash +# Start services +docker-compose -f docker/docker-compose.dev.yml up -d + +# Stop services +docker-compose -f docker/docker-compose.dev.yml down + +# View logs +docker-compose -f docker/docker-compose.dev.yml logs -f [service-name] + +# Execute commands in container +docker-compose -f docker/docker-compose.dev.yml exec [service-name] [command] + +# Scale services +docker-compose -f docker/docker-compose.dev.yml up -d --scale [service-name]=[count] + +# Build images +./docker/build.sh [image-name] + +# Health check +docker-compose -f docker/docker-compose.dev.yml exec [service-name] /usr/local/bin/health-check.sh +``` + +Happy developing with Apache Ambari on Docker! 🐳 diff --git a/docker/images/ambari/README.md b/docker/images/ambari/README.md new file mode 100644 index 00000000000..0181c639d51 --- /dev/null +++ b/docker/images/ambari/README.md @@ -0,0 +1,618 @@ +# docker-ambari + +This is a docker image of [Apache Ambari](https://github.com/apache/ambari). + +## How to build a docker image + +There is a docker build script which will build a given Git repo/branch and tag the image. + +Usage: +```bash +./docker-build.sh [Docker Tag] [Git Branch] [Ambari Git URL] [Kafka Version] [Java Version] [JDK Version] [OpenJDK Image] +``` + +This script will check out Ambari Repo `[Ambari Git URL]` on branch `[Git Branch]` and build the docker image for that. + +The docker image is tagged as `[Docker Tag]`. + +**Parameters:** +- `Docker Tag`: Name and tag your docker image. Default is `ambari:latest`. +- `Git Branch`: The Ambari branch to build. Default is `trunk`. +- `Ambari Git URL`: The Ambari Git Repo to build, users can set it to their own fork. Please note that, the URL is `https://` based, not `git://`. Default is the Apache Repo: `https://github.com/apache/ambari.git`. +- `Kafka Version`: The Kafka Version to build ambari with. Default is `2.0` +- `Java Version`: The Java Build and Runtime image version. Default is `8` +- `JDK Version`: The JDK parameter to build ambari, set as part of maven build option: `-Djdk.version=${JDK_VERSION}`. Default is `8` +- `OpenJDK Image`: Base image to use for Ambari build and runtime. Default is `openjdk`. + +### Examples + +* Example of building and tagging a snapshot on your own fork: +```bash +./docker-build.sh ambari_fork:snapshot-3.0 snapshot-3.0 https://github.com/your_own_fork/ambari.git +``` + +* Example of building a release version: +```bash +./docker-build.sh ambari:release-2.7.5 release-2.7.5 https://github.com/apache/ambari.git +``` + +### Build image with arm64 base image + +For users on Mac M1 chips, they need to build the images with arm64 base image, e.g. `arm64v8/openjdk` + +* Example of building an arm64 image: +```bash +./docker-build.sh ambari:latest trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk +``` + +or just run the docker build script directly: +```bash +docker build -t ambari:latest --no-cache --network=host \ + --build-arg AMBARI_GIT_URL=https://github.com/apache/ambari.git \ + --build-arg AMBARI_BRANCH=trunk \ + --build-arg JDK_VERSION=8 \ + --build-arg OPENJDK_IMAGE=arm64v8/openjdk \ + -f Dockerfile . +``` + +Note that if you are not on arm64 machine, you can still build the image by turning on the experimental feature of docker, and add `--platform linux/arm64` into the `docker build ...` script. + +## How to publish a docker image + +Script `docker-push.sh` publishes a given docker image to your docker registry. + +In order to push to your own repo, the image needs to be explicitly tagged with the repo name. + +* Example of publishing a image to [apache/ambari](https://hub.docker.com/r/apache/ambari) dockerHub repo: +```bash +./docker-push.sh apache/ambari:latest +``` + +* Tag a built image, then push: +```bash +docker tag ambari:release-2.7.5 apache/ambari:release-2.7.5 +docker push apache/ambari:release-2.7.5 +``` + +Script `docker-build-and-push.sh` builds and publishes this docker image to your docker registry after build. + +* Example of building and publishing a image to [apache/ambari](https://hub.docker.com/r/apache/ambari) dockerHub repo: +```bash +./docker-build-and-push.sh apache/ambari:latest trunk https://github.com/apache/ambari.git +``` + +## How to Run it + +The entry point of docker image is `ambari-admin.sh` script. + +### Bring up PostgreSQL Database + +Example of bring up a local PostgreSQL database in docker: +```bash +docker pull postgres:13-alpine +docker run --name ambari-database --restart always -p 5432:5432 \ + -e POSTGRES_DB=ambari \ + -e POSTGRES_USER=ambari \ + -e POSTGRES_PASSWORD=bigdata \ + postgres:13-alpine +``` + +You can extract the database host from: +```bash +docker inspect ambari-database | grep IPAddress + "SecondaryIPAddresses": null, + "IPAddress": "172.17.0.2", + "IPAddress": "172.17.0.2", +``` + +Please use local database path `172.17.0.2:5432` as database host parameter. + +### Ambari Server + +Example of bring up a local Ambari Server: +```bash +docker run -p 8080:8080 \ + -e AMBARI_DB_HOST=172.17.0.2 \ + -e AMBARI_DB_PORT=5432 \ + -e AMBARI_DB_NAME=ambari \ + -e AMBARI_DB_USER=ambari \ + -e AMBARI_DB_PASSWORD=bigdata \ + apache/ambari:latest StartServer +``` + +### Ambari Agent + +Example of bring up a local Ambari Agent: +```bash +docker run \ + -e AMBARI_SERVER_HOST=172.17.0.3 \ + -e AMBARI_SERVER_PORT=8080 \ + --privileged \ + apache/ambari:latest StartAgent +``` + +### Ambari Metrics Collector (Optional) + +Example of bring up Ambari Metrics Collector: +```bash +docker run -p 6188:6188 \ + -e AMS_HBASE_ROOTDIR=/var/lib/ambari-metrics-collector/hbase \ + -e AMS_COLLECTOR_PORT=6188 \ + apache/ambari:latest StartMetrics +``` + +## QuickStart + +### Use docker compose to bring up Ambari stack + +Below is a script to use docker compose to bring up database/ambari-server/ambari-agent + +```bash +docker-compose -f docker-compose.yml up +``` + +### Enable Optional Components + +#### Enable Metrics Collection +```bash +export METRICS_ENABLED=1 +docker-compose --profile metrics -f docker-compose.yml up +``` + +#### Enable Grafana Dashboard +```bash +export METRICS_ENABLED=1 +export GRAFANA_ENABLED=1 +docker-compose --profile metrics -f docker-compose.yml up +``` + +#### Enable Zookeeper and Kafka +```bash +export ZOOKEEPER_ENABLED=1 +export KAFKA_ENABLED=1 +docker-compose --profile zookeeper --profile kafka -f docker-compose.yml up +``` + +#### Enable All Components +```bash +export METRICS_ENABLED=1 +export GRAFANA_ENABLED=1 +export ZOOKEEPER_ENABLED=1 +export KAFKA_ENABLED=1 +docker-compose --profile metrics --profile zookeeper --profile kafka -f docker-compose.yml up +``` + +### Scale Ambari Agents + +You can scale the number of Ambari agents: +```bash +docker-compose -f docker-compose.yml up -d --scale ambari-agent=3 +``` + +### Access Services + +Once your cluster is up and running: + +- **Ambari Web UI**: http://localhost:8080 (admin/admin) +- **Grafana Dashboard**: http://localhost:3000 (admin/admin) - if enabled +- **Metrics API**: http://localhost:6188/ws/v1/timeline/metrics/metadata - if enabled +- **Database**: localhost:5432 (ambari/bigdata) + +## Configuration + +### Environment Variables + +#### Ambari Server +- `AMBARI_DB_HOST`: Database hostname (default: ambari-database) +- `AMBARI_DB_PORT`: Database port (default: 5432) +- `AMBARI_DB_NAME`: Database name (default: ambari) +- `AMBARI_DB_USER`: Database user (default: ambari) +- `AMBARI_DB_PASSWORD`: Database password (default: bigdata) +- `AMBARI_SERVER_HTTPS`: Enable HTTPS (default: false) +- `JAVA_OPTS`: JVM options + +#### Ambari Agent +- `AMBARI_SERVER_HOST`: Ambari Server hostname (default: ambari-server) +- `AMBARI_SERVER_PORT`: Ambari Server port (default: 8080) +- `AGENT_HOSTNAME`: Agent hostname (auto-detected if not set) + +#### Ambari Metrics (Optional) +- `AMS_HBASE_ROOTDIR`: HBase root directory (default: /var/lib/ambari-metrics-collector/hbase) +- `AMS_COLLECTOR_PORT`: Collector port (default: 6188) + +#### Optional Components Control +- `METRICS_ENABLED`: Enable metrics collection (0 or 1, default: 0) +- `GRAFANA_ENABLED`: Enable Grafana dashboard (0 or 1, default: 0) +- `ZOOKEEPER_ENABLED`: Enable Zookeeper (0 or 1, default: 0) +- `KAFKA_ENABLED`: Enable Kafka (0 or 1, default: 0) + +### Docker Images +- `AMBARI_IMAGE`: Ambari image to use (default: apache/ambari:latest) +- `POSTGRES_IMAGE`: PostgreSQL image to use (default: postgres:13-alpine) +- `ZK_IMAGE`: Zookeeper image to use (default: zookeeper:3.8.1) +- `KAFKA_IMAGE`: Kafka image to use (default: bitnami/kafka:3.6) + +## Available Dockerfiles + +### Dockerfile +Main production Dockerfile that builds Ambari from source and creates a runtime image. + +### Dockerfile.build +Build-only Dockerfile for development environments with all build tools. + +### Dockerfile.package +Package-based Dockerfile that uses pre-built Ambari packages instead of building from source. + +## Troubleshooting + +### Common Issues + +#### Container Won't Start +```bash +# Check logs +docker-compose logs ambari-server + +# Check container status +docker-compose ps + +# Restart specific service +docker-compose restart ambari-server +``` + +#### Database Connection Issues +```bash +# Verify database is running +docker-compose exec ambari-database pg_isready -U ambari + +# Check database logs +docker-compose logs ambari-database + +# Reset database +docker-compose down -v +docker-compose up -d ambari-database +``` + +#### Memory Issues +```bash +# Check resource usage +docker stats + +# Increase memory limits in docker-compose.yml +services: + ambari-server: + deploy: + resources: + limits: + memory: 4G +``` + +### Health Checks + +All services include health checks: +- **Server**: HTTP check on `/api/v1/clusters` +- **Agent**: Process and heartbeat check +- **Metrics**: HTTP check on `/ws/v1/timeline/metrics/metadata` +- **Database**: Connection check + +### Debug Mode + +Enable debug logging: +```bash +export AMBARI_DEBUG=true +docker-compose up -d +``` + +## Security Considerations + +### Production Deployment +1. Change default passwords +2. Use external database with proper credentials +3. Enable HTTPS/TLS +4. Configure firewall rules +5. Use secrets management +6. Regular security updates + +### Network Security +```yaml +# Example secure configuration +services: + ambari-server: + environment: + - AMBARI_DB_PASSWORD_FILE=/run/secrets/db_password + secrets: + - db_password + +secrets: + db_password: + external: true +``` + +## Performance Tuning + +### Resource Allocation +```yaml +# Recommended production resources +services: + ambari-server: + deploy: + resources: + limits: + memory: 4G + cpus: '2.0' + reservations: + memory: 2G + cpus: '1.0' +``` + +### JVM Tuning +```bash +# Server JVM options +JAVA_OPTS="-Xmx2g -Xms1g -XX:+UseG1GC" + +# Metrics JVM options +JAVA_OPTS="-Xmx1g -Xms512m" +``` + +## Testing and Deployment Workflows + +### Complete Build and Test Workflow + +#### 1. Build Base Images First +```bash +# Build base image (required for all other builds) +cd docker/images/ambari-base +./docker-build.sh ambari-base:latest + +# Build metrics base (optional) +cd ../ambari-metrics +./docker-build.sh ambari-metrics:latest +``` + +#### 2. Build Main Ambari Image +```bash +# Build from current branch +cd ../ambari +./docker-build.sh ambari:latest + +# Build from specific branch/fork +./docker-build.sh ambari:my-feature feature-branch https://github.com/myuser/ambari.git + +# Build with custom options +./docker-build.sh ambari:arm64 trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk +``` + +#### 3. Test the Built Images +```bash +# Quick test - start basic services +./quick-test.sh + +# Minimal test - server only +./minimal-test.sh + +# Full test - all components +./simple-test.sh + +# Manual testing with docker-compose +docker-compose up -d +docker-compose ps +docker-compose logs ambari-server +``` + +#### 4. Verify Functionality +```bash +# Check server health +curl http://localhost:8080/api/v1/clusters + +# Check metrics (if enabled) +curl http://localhost:6188/ws/v1/timeline/metrics/metadata + +# Access web UI +open http://localhost:8080 # admin/admin +``` + +### Publishing Images to Registry + +#### 1. Tag Images Properly +```bash +# Tag for Docker Hub +docker tag ambari:latest apache/ambari:latest +docker tag ambari:latest apache/ambari:$(date +%Y%m%d) + +# Tag for custom registry +docker tag ambari:latest myregistry.com/ambari:latest +``` + +#### 2. Push Using Scripts +```bash +# Push to Docker Hub +./docker-push.sh apache/ambari:latest + +# Push with authentication +./docker-push.sh apache/ambari:latest --username myuser --password mypass + +# Push to custom registry +./docker-push.sh myregistry.com/ambari:latest --registry myregistry.com + +# Dry run to verify +./docker-push.sh apache/ambari:latest --dry-run +``` + +#### 3. Build and Push in One Step +```bash +# Build and push latest +./docker-build-and-push.sh apache/ambari:latest + +# Build specific branch and push +./docker-build-and-push.sh apache/ambari:feature-v1 feature-branch https://github.com/myuser/ambari.git +``` + +### Automated CI/CD Pipeline Example + +#### GitHub Actions Workflow +```yaml +name: Build and Push Ambari Docker Images + +on: + push: + branches: [ main, trunk ] + pull_request: + branches: [ main ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Build Base Image + run: | + cd docker/images/ambari-base + ./docker-build.sh ambari-base:${{ github.sha }} + + - name: Build Main Image + run: | + cd docker/images/ambari + ./docker-build.sh ambari:${{ github.sha }} + + - name: Test Images + run: | + cd docker/images/ambari + ./quick-test.sh + + - name: Push to Registry + if: github.ref == 'refs/heads/main' + run: | + echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + ./docker-push.sh apache/ambari:${{ github.sha }} + ./docker-push.sh apache/ambari:latest +``` + +### Development Workflow + +#### 1. Local Development Setup +```bash +# Clone and setup +git clone https://github.com/apache/ambari.git +cd ambari + +# Build development image +cd docker/images/ambari +./docker-build.sh ambari:dev trunk https://github.com/apache/ambari.git + +# Start development environment +docker-compose -f docker-compose.dev.yml up -d +``` + +#### 2. Testing Changes +```bash +# Rebuild after changes +./docker-build.sh ambari:dev --no-cache + +# Test specific components +docker-compose restart ambari-server +docker-compose logs -f ambari-server + +# Run integration tests +./TESTING.md # Follow testing guide +``` + +#### 3. Multi-Architecture Builds +```bash +# Setup buildx for multi-arch +docker buildx create --name multiarch --use +docker buildx inspect --bootstrap + +# Build for multiple platforms +docker buildx build --platform linux/amd64,linux/arm64 \ + -t apache/ambari:latest \ + --push . +``` + +### Production Deployment + +#### 1. Pre-deployment Checklist +- [ ] Images tested in staging environment +- [ ] Security scan completed +- [ ] Performance benchmarks met +- [ ] Documentation updated +- [ ] Rollback plan prepared + +#### 2. Blue-Green Deployment +```bash +# Deploy to green environment +docker-compose -f docker-compose.prod.yml -p ambari-green up -d + +# Verify green environment +curl http://green-ambari:8080/api/v1/clusters + +# Switch traffic (update load balancer) +# Monitor and rollback if needed + +# Cleanup old blue environment +docker-compose -p ambari-blue down +``` + +#### 3. Rolling Updates +```bash +# Update images one by one +docker-compose pull +docker-compose up -d --no-deps ambari-server +# Wait and verify +docker-compose up -d --no-deps ambari-agent +``` + +### Monitoring and Maintenance + +#### 1. Health Monitoring +```bash +# Check all services +docker-compose ps +docker stats + +# Monitor logs +docker-compose logs -f --tail=100 + +# Health check endpoints +curl http://localhost:8080/api/v1/clusters +curl http://localhost:6188/ws/v1/timeline/metrics/metadata +``` + +#### 2. Backup and Recovery +```bash +# Backup database +docker-compose exec ambari-database pg_dump -U ambari ambari > backup.sql + +# Backup configurations +docker cp ambari_ambari-server_1:/etc/ambari-server/conf ./backup/ + +# Restore from backup +docker-compose exec -T ambari-database psql -U ambari ambari < backup.sql +``` + +## Contributing + +### Adding New Services +1. Create Dockerfile in appropriate location +2. Add to docker-compose.yml +3. Update documentation +4. Add health checks +5. Test thoroughly + +### Testing Changes +```bash +# Run basic test +docker-compose up -d +docker-compose ps + +# Test specific component +docker-compose logs ambari-server + +# Clean test environment +docker-compose down -v +``` + +## Support + +- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/) +- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues) +- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html) diff --git a/docker/images/ambari/TESTING.md b/docker/images/ambari/TESTING.md new file mode 100644 index 00000000000..b22d18bf2ea --- /dev/null +++ b/docker/images/ambari/TESTING.md @@ -0,0 +1,417 @@ +# Apache Ambari Docker Testing Guide + +This guide provides complete step-by-step testing instructions for the improved Ambari Docker setup. + +## Prerequisites + +Before testing, ensure you have: +- Docker 20.10+ installed +- Docker Compose 2.0+ installed +- At least 16GB RAM available +- At least 50GB free disk space +- Git (to clone the repository) + +## Step 1: Environment Setup + +```bash +# Check Docker installation +docker --version +docker-compose --version + +# Check system resources +docker system info | grep -E "CPUs|Total Memory" +df -h # Check disk space + +# Navigate to Ambari project directory +cd /path/to/ambari # Replace with your actual path +pwd # Should show the ambari directory +``` + +## Step 2: Build Docker Images + +```bash +# Make build script executable +chmod +x docker/build.sh + +# Build all images (this will take 15-30 minutes) +./docker/build.sh all + +# Verify images are created +docker images | grep ambari + +# Expected output should show: +# apache/ambari-server latest +# apache/ambari-agent latest +# apache/ambari-metrics latest +# apache/ambari-base latest +``` + +## Step 3: Start the Complete Stack + +```bash +# Start all services in detached mode +docker-compose -f docker/docker-compose.yml up -d + +# Wait for services to start (2-5 minutes) +# Monitor the startup process +docker-compose -f docker/docker-compose.yml logs -f + +# Check all containers are running +docker-compose -f docker/docker-compose.yml ps + +# Expected output: All services should show "Up" status +``` + +## Step 4: Basic Health Verification + +```bash +# Wait for all services to be healthy (may take 5-10 minutes) +watch docker-compose -f docker/docker-compose.yml ps + +# Check individual service health +docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server +docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent +docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics + +# All health checks should return "Status: HEALTHY" +``` + +## Step 5: Web Interface Testing + +### Test Ambari Web UI +```bash +# Open Ambari Web UI +open http://localhost:8080 +# Or use: curl -I http://localhost:8080 + +# Login credentials: +# Username: admin +# Password: admin + +# You should see the Ambari welcome screen +``` + +### Test Grafana Dashboard +```bash +# Open Grafana +open http://localhost:3000 +# Or use: curl -I http://localhost:3000 + +# Login credentials: +# Username: admin +# Password: admin + +# You should see the Grafana dashboard +``` + +### Test Hadoop Web UIs +```bash +# Test NameNode UI +curl -I http://localhost:9870 +open http://localhost:9870 + +# Test ResourceManager UI +curl -I http://localhost:8088 +open http://localhost:8088 + +# Both should return HTTP 200 OK +``` + +## Step 6: API Testing + +```bash +# Test Ambari Server API +curl -u admin:admin http://localhost:8080/api/v1/clusters +# Expected: JSON response with cluster information + +# Test Ambari version info +curl -u admin:admin http://localhost:8080/api/v1/version +# Expected: JSON with version details + +# Test Metrics Collector API +curl http://localhost:6188/ws/v1/timeline/metrics/metadata +# Expected: JSON response with metrics metadata + +# Test Grafana API +curl http://localhost:3000/api/health +# Expected: {"commit":"","database":"ok","version":""} +``` + +## Step 7: Database Testing + +```bash +# Connect to PostgreSQL database +docker-compose -f docker/docker-compose.yml exec ambari-db psql -U ambari -d ambari + +# Run these SQL commands: +\dt # List tables +SELECT COUNT(*) FROM users; # Should return 1 (admin user) +SELECT user_name FROM users; # Should show 'admin' +\q # Exit + +# Test database connectivity from server +docker-compose -f docker/docker-compose.yml exec ambari-server pg_isready -h ambari-db -p 5432 -U ambari +# Expected: ambari-db:5432 - accepting connections +``` + +## Step 8: Zookeeper Testing + +```bash +# Check Zookeeper status +docker-compose -f docker/docker-compose.yml exec zookeeper zkServer.sh status +# Expected: Mode: standalone + +# Connect to Zookeeper CLI +docker-compose -f docker/docker-compose.yml exec zookeeper zkCli.sh -server localhost:2181 + +# Run these commands in ZK CLI: +ls / # List root znodes +create /test "data" # Create test node +get /test # Get test node data +delete /test # Delete test node +quit # Exit ZK CLI +``` + +## Step 9: Hadoop Cluster Testing + +```bash +# Check HDFS status +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report +# Expected: Shows DataNode information + +# Test HDFS operations +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -mkdir /test +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -ls / +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -put /etc/hosts /test/ +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -cat /test/hosts +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -rm -r /test + +# Check YARN nodes +docker-compose -f docker/docker-compose.yml exec resourcemanager yarn node -list +# Expected: Shows active NodeManagers +``` + +## Step 10: Agent Registration Testing + +```bash +# Check agent logs for registration +docker-compose -f docker/docker-compose.yml logs ambari-agent | grep -i "registration" + +# Verify agent is registered in Ambari +curl -u admin:admin http://localhost:8080/api/v1/hosts +# Expected: JSON showing registered hosts + +# Check agent heartbeat +docker-compose -f docker/docker-compose.yml logs ambari-server | grep -i "heartbeat" | tail -5 +# Expected: Recent heartbeat messages +``` + +## Step 11: Metrics Collection Testing + +```bash +# Check metrics collector status +curl http://localhost:6188/ws/v1/timeline/metrics/metadata | jq . +# Expected: JSON with metrics metadata + +# Verify HBase is running (embedded in metrics collector) +docker-compose -f docker/docker-compose.yml exec ambari-metrics ps aux | grep HMaster +# Expected: HMaster process running + +# Test metrics query (wait 5 minutes after startup) +curl "http://localhost:6188/ws/v1/timeline/metrics?metricNames=cpu_user&hostname=ambari-agent&appId=HOST&startTime=$(date -d '1 hour ago' +%s)000&endTime=$(date +%s)000" | jq . +# Expected: JSON with CPU metrics data +``` + +## Step 12: Scaling Testing + +```bash +# Scale agents to 3 instances +docker-compose -f docker/docker-compose.yml up -d --scale ambari-agent=3 + +# Wait for new agents to register (2-3 minutes) +sleep 180 + +# Verify all agents are registered +curl -u admin:admin http://localhost:8080/api/v1/hosts | jq '.items[].Hosts.host_name' +# Expected: Should show 3 agent hostnames + +# Scale DataNodes to 3 instances +docker-compose -f docker/docker-compose.yml up -d --scale datanode=3 + +# Check DataNode status +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report +# Expected: Should show 3 DataNodes +``` + +## Step 13: Performance Testing + +```bash +# Monitor resource usage +docker stats --no-stream + +# Check container health over time +for i in {1..5}; do + echo "=== Health Check $i ===" + docker-compose -f docker/docker-compose.yml ps + sleep 30 +done + +# Test API response times +time curl -u admin:admin http://localhost:8080/api/v1/clusters +time curl http://localhost:6188/ws/v1/timeline/metrics/metadata +# Response times should be under 2 seconds +``` + +## Step 14: Failure Recovery Testing + +```bash +# Test container restart +docker-compose -f docker/docker-compose.yml restart ambari-server + +# Wait for restart and check health +sleep 60 +docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server + +# Test database recovery +docker-compose -f docker/docker-compose.yml restart ambari-db +sleep 30 +docker-compose -f docker/docker-compose.yml exec ambari-db pg_isready -U ambari + +# Verify services recover +curl -u admin:admin http://localhost:8080/api/v1/clusters +``` + +## Step 15: Development Environment Testing + +```bash +# Start development environment +docker-compose -f docker/docker-compose.dev.yml up -d + +# Enter development container +docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash + +# Inside container, test build environment +cd /workspace +mvn --version +java -version +node --version + +# Test Maven build (inside container) +mvn clean compile -DskipTests -pl ambari-server + +# Exit container +exit + +# Stop development environment +docker-compose -f docker/docker-compose.dev.yml down +``` + +## Expected Test Results + +### ✅ Success Criteria + +All tests should pass with these results: + +1. **Images Built**: 4 Ambari images created successfully +2. **Services Running**: All containers show "Up (healthy)" status +3. **Web UIs Accessible**: + - Ambari UI at http://localhost:8080 + - Grafana at http://localhost:3000 + - NameNode UI at http://localhost:9870 + - ResourceManager UI at http://localhost:8088 +4. **APIs Responding**: All curl commands return valid JSON +5. **Database Connected**: PostgreSQL accessible with admin user +6. **Zookeeper Working**: Can create/read/delete znodes +7. **HDFS Operational**: Can create directories and files +8. **Agents Registered**: At least 1 agent heartbeating +9. **Metrics Collecting**: Metrics API returns data +10. **Scaling Works**: Can scale agents and DataNodes + +### ❌ Troubleshooting Common Issues + +#### Issue: Containers not starting +```bash +# Check logs +docker-compose -f docker/docker-compose.yml logs [service-name] + +# Check resources +docker system df +docker system info | grep Memory + +# Solution: Increase Docker memory or reduce JVM heap sizes +``` + +#### Issue: Port conflicts +```bash +# Check port usage +lsof -i :8080 +lsof -i :5432 + +# Solution: Change ports in docker-compose.yml +``` + +#### Issue: Health checks failing +```bash +# Manual health check +docker-compose -f docker/docker-compose.yml exec [service] /usr/local/bin/health-check.sh [component] + +# Check service logs +docker-compose -f docker/docker-compose.yml logs [service] + +# Solution: Wait longer for startup or check configuration +``` + +## Cleanup After Testing + +```bash +# Stop all services +docker-compose -f docker/docker-compose.yml down + +# Remove volumes (WARNING: Deletes all data) +docker-compose -f docker/docker-compose.yml down -v + +# Clean up images (optional) +docker images | grep ambari | awk '{print $3}' | xargs docker rmi + +# Clean up system +docker system prune -f +``` + +## Automated Testing Script + +Create a test script for automated testing: + +```bash +# Create test script +cat > test-ambari-docker.sh << 'EOF' +#!/bin/bash +set -e + +echo "=== Starting Ambari Docker Tests ===" + +# Build images +echo "Building images..." +./docker/build.sh all + +# Start services +echo "Starting services..." +docker-compose -f docker/docker-compose.yml up -d + +# Wait for services +echo "Waiting for services to start..." +sleep 300 + +# Run tests +echo "Testing APIs..." +curl -f -u admin:admin http://localhost:8080/api/v1/clusters +curl -f http://localhost:6188/ws/v1/timeline/metrics/metadata +curl -f http://localhost:3000/api/health + +echo "=== All tests passed! ===" +EOF + +chmod +x test-ambari-docker.sh +./test-ambari-docker.sh +``` + +This comprehensive testing guide ensures that all components of the improved Ambari Docker setup are working correctly and provides troubleshooting steps for common issues. diff --git a/docker/images/ambari/VERIFICATION.md b/docker/images/ambari/VERIFICATION.md new file mode 100644 index 00000000000..0c1a1d1325e --- /dev/null +++ b/docker/images/ambari/VERIFICATION.md @@ -0,0 +1,383 @@ +# Apache Ambari Docker Verification Guide + +This guide provides step-by-step instructions to verify the Ambari Docker setup and ensure all components are working correctly. + +## Prerequisites + +- Docker 20.10+ installed and running +- Docker Compose 2.0+ installed +- At least 16GB RAM available for Docker +- At least 50GB free disk space + +## Quick Verification Steps + +### 1. Environment Check + +```bash +# Check Docker version +docker --version +docker-compose --version + +# Check available resources +docker system df +docker system info | grep -E "CPUs|Total Memory" + +# Ensure you're in the Ambari project root +pwd # Should show /path/to/ambari +ls docker/ # Should show docker-compose.yml and Dockerfiles +``` + +### 2. Build Images + +```bash +# Build all Ambari images +./docker/build.sh all + +# Or build specific images +./docker/build.sh server +./docker/build.sh agent +./docker/build.sh metrics + +# Verify images are built +docker images | grep ambari +``` + +### 3. Start the Complete Stack + +```bash +# Start all services +docker-compose -f docker/docker-compose.yml up -d + +# Check service status +docker-compose -f docker/docker-compose.yml ps + +# Monitor startup logs +docker-compose -f docker/docker-compose.yml logs -f +``` + +### 4. Verify Service Health + +```bash +# Check all container health status +docker-compose -f docker/docker-compose.yml ps + +# Check individual service health +docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server +docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent +docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics +``` + +### 5. Access Web Interfaces + +```bash +# Ambari Web UI +open http://localhost:8080 +# Default credentials: admin/admin + +# Grafana Dashboard +open http://localhost:3000 +# Default credentials: admin/admin + +# Hadoop NameNode UI +open http://localhost:9870 + +# YARN ResourceManager UI +open http://localhost:8088 +``` + +### 6. API Verification + +```bash +# Test Ambari Server API +curl -u admin:admin http://localhost:8080/api/v1/clusters + +# Test Metrics Collector API +curl http://localhost:6188/ws/v1/timeline/metrics/metadata + +# Test Grafana API +curl http://localhost:3000/api/health +``` + +## Detailed Verification Steps + +### Database Verification + +```bash +# Connect to PostgreSQL database +docker-compose -f docker/docker-compose.yml exec ambari-db psql -U ambari -d ambari + +# Check database tables +\dt + +# Verify admin user exists +SELECT user_name, admin FROM users WHERE user_name = 'admin'; + +# Exit database +\q +``` + +### Zookeeper Verification + +```bash +# Check Zookeeper status +docker-compose -f docker/docker-compose.yml exec zookeeper zkServer.sh status + +# Connect to Zookeeper CLI +docker-compose -f docker/docker-compose.yml exec zookeeper zkCli.sh + +# List root znodes +ls / + +# Exit Zookeeper CLI +quit +``` + +### Hadoop Cluster Verification + +```bash +# Check HDFS status +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report + +# Create test directory in HDFS +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -mkdir /test + +# List HDFS contents +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfs -ls / + +# Check YARN nodes +docker-compose -f docker/docker-compose.yml exec resourcemanager yarn node -list +``` + +### Agent Registration Verification + +```bash +# Check agent logs +docker-compose -f docker/docker-compose.yml logs ambari-agent + +# Verify agent registration in Ambari Server +curl -u admin:admin http://localhost:8080/api/v1/hosts + +# Check agent heartbeat +docker-compose -f docker/docker-compose.yml exec ambari-server tail -f /var/log/ambari-server/ambari-server.log | grep heartbeat +``` + +### Metrics Collection Verification + +```bash +# Check metrics collector status +curl http://localhost:6188/ws/v1/timeline/metrics/metadata + +# Verify HBase is running (embedded in metrics collector) +docker-compose -f docker/docker-compose.yml exec ambari-metrics ps aux | grep HMaster + +# Check metrics data +curl "http://localhost:6188/ws/v1/timeline/metrics?metricNames=cpu_user&hostname=ambari-agent&appId=HOST&startTime=$(date -d '1 hour ago' +%s)000&endTime=$(date +%s)000" +``` + +## Scaling and Load Testing + +### Scale Agents + +```bash +# Scale to 3 agents +docker-compose -f docker/docker-compose.yml up -d --scale ambari-agent=3 + +# Verify all agents are registered +curl -u admin:admin http://localhost:8080/api/v1/hosts | jq '.items[].Hosts.host_name' +``` + +### Scale DataNodes + +```bash +# Scale to 3 DataNodes +docker-compose -f docker/docker-compose.yml up -d --scale datanode=3 + +# Check DataNode status +docker-compose -f docker/docker-compose.yml exec namenode hdfs dfsadmin -report +``` + +## Troubleshooting + +### Common Issues and Solutions + +#### 1. Services Won't Start + +```bash +# Check logs for specific service +docker-compose -f docker/docker-compose.yml logs [service-name] + +# Check resource usage +docker stats + +# Restart specific service +docker-compose -f docker/docker-compose.yml restart [service-name] +``` + +#### 2. Database Connection Issues + +```bash +# Check database status +docker-compose -f docker/docker-compose.yml exec ambari-db pg_isready -U ambari + +# Reset database +docker-compose -f docker/docker-compose.yml down +docker volume rm ambari_ambari-db-data +docker-compose -f docker/docker-compose.yml up -d ambari-db +``` + +#### 3. Port Conflicts + +```bash +# Check what's using ports +lsof -i :8080 +lsof -i :5432 + +# Modify ports in docker-compose.yml if needed +# Example: Change "8080:8080" to "8081:8080" +``` + +#### 4. Memory Issues + +```bash +# Check Docker memory limit +docker system info | grep Memory + +# Reduce JVM heap sizes in docker-compose.yml +# Example: Change JAVA_OPTS from -Xmx4G to -Xmx2G +``` + +### Health Check Commands + +```bash +# Manual health checks +docker-compose -f docker/docker-compose.yml exec ambari-server /usr/local/bin/health-check.sh server +docker-compose -f docker/docker-compose.yml exec ambari-agent /usr/local/bin/health-check.sh agent +docker-compose -f docker/docker-compose.yml exec ambari-metrics /usr/local/bin/health-check.sh metrics + +# Check all container health +docker-compose -f docker/docker-compose.yml ps +``` + +### Log Analysis + +```bash +# View all logs +docker-compose -f docker/docker-compose.yml logs + +# Follow specific service logs +docker-compose -f docker/docker-compose.yml logs -f ambari-server + +# Search for errors +docker-compose -f docker/docker-compose.yml logs | grep -i error + +# Check last 100 lines +docker-compose -f docker/docker-compose.yml logs --tail=100 ambari-server +``` + +## Performance Monitoring + +### Resource Usage + +```bash +# Monitor container resource usage +docker stats + +# Check disk usage +docker system df + +# Monitor network traffic +docker-compose -f docker/docker-compose.yml exec ambari-server netstat -tuln +``` + +### Metrics Dashboard + +1. Access Grafana at http://localhost:3000 +2. Login with admin/admin +3. Import Ambari dashboards from `/docker/config/grafana/dashboards/` +4. Monitor cluster metrics in real-time + +## Development Workflow + +### Live Development + +```bash +# Start development environment +docker-compose -f docker/docker-compose.dev.yml up -d + +# Enter development container +docker-compose -f docker/docker-compose.dev.yml exec ambari-server bash + +# Build and test changes +cd /workspace +mvn clean install -DskipTests + +# Restart services after changes +docker-compose -f docker/docker-compose.dev.yml restart ambari-server +``` + +### Debugging + +```bash +# Enable debug mode +export AMBARI_DEBUG=true +docker-compose -f docker/docker-compose.yml up -d + +# Connect debugger to: +# - Server: localhost:5005 +# - Agent: localhost:5006 + +# Access container shell +docker-compose -f docker/docker-compose.yml exec ambari-server bash +``` + +## Cleanup + +### Stop Services + +```bash +# Stop all services +docker-compose -f docker/docker-compose.yml down + +# Stop and remove volumes (WARNING: This deletes all data) +docker-compose -f docker/docker-compose.yml down -v +``` + +### Clean Up Images + +```bash +# Remove Ambari images +docker images | grep ambari | awk '{print $3}' | xargs docker rmi + +# Clean up system +docker system prune -a +``` + +## Success Criteria + +Your Ambari Docker setup is successfully verified when: + +1. ✅ All containers are running and healthy +2. ✅ Ambari Web UI is accessible at http://localhost:8080 +3. ✅ Database connection is working +4. ✅ At least one agent is registered and heartbeating +5. ✅ Metrics collector is receiving data +6. ✅ Grafana dashboards are displaying metrics +7. ✅ Hadoop cluster (NameNode, DataNodes, ResourceManager) is operational +8. ✅ API endpoints are responding correctly + +## Next Steps + +After successful verification: + +1. **Cluster Setup**: Use Ambari Web UI to install Hadoop services +2. **Security**: Configure Kerberos and SSL/TLS for production +3. **Monitoring**: Set up alerts and monitoring dashboards +4. **Backup**: Configure database and HDFS backups +5. **Scaling**: Add more agents and DataNodes as needed + +## Getting Help + +- **Documentation**: [Apache Ambari Docs](https://ambari.apache.org/) +- **Issues**: [GitHub Issues](https://github.com/apache/ambari/issues) +- **Community**: [Apache Ambari Mailing Lists](https://ambari.apache.org/mail-lists.html) +- **Docker Logs**: `docker-compose -f docker/docker-compose.yml logs` diff --git a/docker/images/ambari/bin/ambari-admin.sh b/docker/images/ambari/bin/ambari-admin.sh new file mode 100755 index 00000000000..ddb04cac461 --- /dev/null +++ b/docker/images/ambari/bin/ambari-admin.sh @@ -0,0 +1,385 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Admin Script +# Similar to Pinot's pinot-admin.sh - main entry point for Ambari Docker containers + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Default environment variables +export AMBARI_HOME=${AMBARI_HOME:-/opt/ambari} +export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-8-openjdk-amd64} +export PATH=${JAVA_HOME}/bin:${AMBARI_HOME}/bin:${PATH} + +# Database configuration +export AMBARI_DB_HOST=${AMBARI_DB_HOST:-ambari-database} +export AMBARI_DB_PORT=${AMBARI_DB_PORT:-5432} +export AMBARI_DB_NAME=${AMBARI_DB_NAME:-ambari} +export AMBARI_DB_USER=${AMBARI_DB_USER:-ambari} +export AMBARI_DB_PASSWORD=${AMBARI_DB_PASSWORD:-bigdata} + +# Server configuration +export AMBARI_SERVER_HOST=${AMBARI_SERVER_HOST:-localhost} +export AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Admin Script + +Usage: $0 [COMMAND] [OPTIONS] + +Available Commands: + StartServer Start Ambari Server + StartAgent Start Ambari Agent + StartMetrics Start Ambari Metrics Collector + QuickStart Start Ambari in quick start mode + +Server Commands: + SetupServer Setup Ambari Server database + ResetServer Reset Ambari Server + UpgradeServer Upgrade Ambari Server + +Agent Commands: + RegisterAgent Register agent with server + +Utility Commands: + CheckHealth Check component health + ShowVersion Show Ambari version + ShowConfig Show current configuration + +Options: + -h, --help Show this help message + -v, --verbose Enable verbose output + --debug Enable debug mode + +Examples: + # Start Ambari Server + $0 StartServer + + # Start Ambari Agent connecting to specific server + $0 StartAgent -server ambari-server + + # Start Metrics Collector + $0 StartMetrics + + # Quick start with all components + $0 QuickStart + + # Setup server with custom database + $0 SetupServer --database postgres --host db.example.com + +Environment Variables: + AMBARI_HOME Ambari installation directory + JAVA_HOME Java installation directory + AMBARI_DB_HOST Database hostname + AMBARI_DB_PORT Database port + AMBARI_DB_NAME Database name + AMBARI_DB_USER Database username + AMBARI_DB_PASSWORD Database password + AMBARI_SERVER_HOST Server hostname (for agents) + AMBARI_SERVER_PORT Server port (for agents) + AMBARI_DEBUG Enable debug output + +EOF +} + +# Function to wait for service +wait_for_service() { + local host=$1 + local port=$2 + local service_name=$3 + local timeout=${4:-60} + + log_info "Waiting for ${service_name} at ${host}:${port}..." + + local count=0 + while ! nc -z "${host}" "${port}" >/dev/null 2>&1; do + if [ ${count} -ge ${timeout} ]; then + log_error "Timeout waiting for ${service_name} at ${host}:${port}" + return 1 + fi + count=$((count + 1)) + sleep 1 + done + + log_info "${service_name} is available at ${host}:${port}" + return 0 +} + +# Function to setup Ambari Server +setup_server() { + log_info "Setting up Ambari Server..." + + # Wait for database + wait_for_service "${AMBARI_DB_HOST}" "${AMBARI_DB_PORT}" "Database" 120 + + # Setup database if not already done + if [ ! -f /var/lib/ambari-server/.db-setup-done ]; then + log_info "Setting up Ambari database..." + ambari-server setup --database=postgres \ + --databasehost="${AMBARI_DB_HOST}" \ + --databaseport="${AMBARI_DB_PORT}" \ + --databasename="${AMBARI_DB_NAME}" \ + --databaseusername="${AMBARI_DB_USER}" \ + --databasepassword="${AMBARI_DB_PASSWORD}" \ + --silent + + touch /var/lib/ambari-server/.db-setup-done + log_info "Database setup completed!" + else + log_info "Database already setup, skipping..." + fi +} + +# Function to start Ambari Server +start_server() { + log_info "Starting Ambari Server..." + + # Setup server first + setup_server + + # Start server + log_info "Starting Ambari Server process..." + exec ambari-server start --debug="${AMBARI_DEBUG:-false}" +} + +# Function to start Ambari Agent +start_agent() { + local server_host="${AMBARI_SERVER_HOST}" + + # Parse additional arguments + while [[ $# -gt 0 ]]; do + case $1 in + -server|--server) + server_host="$2" + shift 2 + ;; + *) + shift + ;; + esac + done + + log_info "Starting Ambari Agent..." + log_info "Server: ${server_host}:${AMBARI_SERVER_PORT}" + + # Wait for server + wait_for_service "${server_host}" "${AMBARI_SERVER_PORT}" "Ambari Server" 300 + + # Configure agent + if [ ! -f /etc/ambari-agent/conf/ambari-agent.ini ]; then + log_info "Configuring Ambari Agent..." + mkdir -p /etc/ambari-agent/conf + cat > /etc/ambari-agent/conf/ambari-agent.ini << EOF +[server] +hostname=${server_host} +url_port=${AMBARI_SERVER_PORT} +secured_url_port=8441 + +[agent] +prefix=/var/lib/ambari-agent/data +cache_dir=/var/lib/ambari-agent/cache +log_dir=/var/log/ambari-agent +run_dir=/var/run/ambari-agent +EOF + fi + + # Start agent + log_info "Starting Ambari Agent process..." + exec ambari-agent start --debug="${AMBARI_DEBUG:-false}" +} + +# Function to start Ambari Metrics +start_metrics() { + log_info "Starting Ambari Metrics Collector..." + + # Configure metrics collector + if [ ! -f /etc/ambari-metrics-collector/conf/ams-site.xml ]; then + log_info "Configuring Ambari Metrics Collector..." + mkdir -p /etc/ambari-metrics-collector/conf + # Add basic configuration here + fi + + # Start metrics collector + log_info "Starting Ambari Metrics Collector process..." + exec ambari-metrics-collector start +} + +# Function for quick start +quick_start() { + log_info "Starting Ambari Quick Start..." + + # Start server in background + start_server & + SERVER_PID=$! + + # Wait a bit for server to start + sleep 30 + + # Start agent + start_agent & + AGENT_PID=$! + + # Wait for both processes + wait $SERVER_PID $AGENT_PID +} + +# Function to check health +check_health() { + log_info "Checking Ambari component health..." + + if command -v /usr/local/bin/health-check.sh >/dev/null 2>&1; then + /usr/local/bin/health-check.sh + else + log_warn "Health check script not found" + return 1 + fi +} + +# Function to show version +show_version() { + log_info "Apache Ambari Version Information" + + if command -v ambari-server >/dev/null 2>&1; then + ambari-server --version 2>/dev/null || echo "Ambari Server: Unknown version" + fi + + if command -v ambari-agent >/dev/null 2>&1; then + ambari-agent --version 2>/dev/null || echo "Ambari Agent: Unknown version" + fi + + echo "Java Version: $(java -version 2>&1 | head -n 1)" + echo "Container: $(hostname)" +} + +# Function to show configuration +show_config() { + log_info "Current Ambari Configuration" + echo "AMBARI_HOME: ${AMBARI_HOME}" + echo "JAVA_HOME: ${JAVA_HOME}" + echo "Database Host: ${AMBARI_DB_HOST}" + echo "Database Port: ${AMBARI_DB_PORT}" + echo "Database Name: ${AMBARI_DB_NAME}" + echo "Database User: ${AMBARI_DB_USER}" + echo "Server Host: ${AMBARI_SERVER_HOST}" + echo "Server Port: ${AMBARI_SERVER_PORT}" + echo "Debug Mode: ${AMBARI_DEBUG:-false}" +} + +# Main function +main() { + local command="${1:-}" + + # Parse global options + while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_usage + exit 0 + ;; + -v|--verbose) + export AMBARI_DEBUG=true + shift + ;; + --debug) + export AMBARI_DEBUG=true + shift + ;; + -*) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + *) + if [[ -z "$command" ]]; then + command="$1" + fi + shift + ;; + esac + done + + # Execute command + case "$command" in + StartServer) + start_server "$@" + ;; + StartAgent) + start_agent "$@" + ;; + StartMetrics) + start_metrics "$@" + ;; + QuickStart) + quick_start "$@" + ;; + SetupServer) + setup_server "$@" + ;; + CheckHealth) + check_health "$@" + ;; + ShowVersion) + show_version "$@" + ;; + ShowConfig) + show_config "$@" + ;; + "") + log_info "No command specified. Starting interactive shell..." + exec /bin/bash + ;; + *) + log_error "Unknown command: $command" + show_usage + exit 1 + ;; + esac +} + +# Run main function +main "$@" diff --git a/docker/images/ambari/docker-build-and-push.sh b/docker/images/ambari/docker-build-and-push.sh new file mode 100755 index 00000000000..133c1c72a33 --- /dev/null +++ b/docker/images/ambari/docker-build-and-push.sh @@ -0,0 +1,394 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Docker Build and Push Script +# Based on Apache Pinot's docker-build-and-push.sh approach + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Docker Build and Push Script + +Usage: $0 [Docker Tag] [Git Branch] [Ambari Git URL] [OPTIONS] + +This script builds and publishes a docker image to your docker registry. +It combines the functionality of docker-build.sh and docker-push.sh. + +Parameters: + Docker Tag Name and tag your docker image (required) + Git Branch The Ambari branch to build (default: trunk) + Ambari Git URL The Ambari Git Repo to build (default: Apache repo) + +Build Options: + --dockerfile DOCKERFILE Use specific Dockerfile (default: Dockerfile) + --no-cache Build without using cache + --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64) + --build-arg KEY=VALUE Pass build argument + +Push Options: + --registry REGISTRY Docker registry URL (default: docker.io) + --username USERNAME Registry username (can also use DOCKER_USERNAME env var) + --password PASSWORD Registry password (can also use DOCKER_PASSWORD env var) + --dry-run Show what would be done without actually doing it + --force Force push even if image exists + --skip-push Build only, skip push + +General Options: + --help Show this help message + +Examples: + # Build and push to Docker Hub (apache/ambari repo): + $0 apache/ambari:latest + + # Build from specific branch and push: + $0 apache/ambari:2.7.5 release-2.7.5 + + # Build from fork and push with authentication: + $0 myregistry.com/ambari:latest trunk https://github.com/myfork/ambari.git \\ + --registry myregistry.com --username myuser --password mypass + + # Build only (skip push): + $0 ambari:dev trunk --skip-push + + # Dry run to see what would be done: + $0 apache/ambari:latest --dry-run + +Environment Variables: + DOCKER_USERNAME Registry username + DOCKER_PASSWORD Registry password + DOCKER_REGISTRY Default registry URL + DOCKER_BUILDKIT Enable BuildKit (recommended: 1) + DEBUG Enable debug output (true/false) + +EOF +} + +# Function to parse arguments +parse_args() { + # Required arguments + DOCKER_TAG="" + GIT_BRANCH="trunk" + AMBARI_GIT_URL="https://github.com/apache/ambari.git" + + # Build options + DOCKERFILE="Dockerfile" + NO_CACHE="" + PLATFORM="" + BUILD_ARGS=() + + # Push options + REGISTRY="${DOCKER_REGISTRY:-docker.io}" + USERNAME="${DOCKER_USERNAME:-}" + PASSWORD="${DOCKER_PASSWORD:-}" + DRY_RUN=false + FORCE=false + SKIP_PUSH=false + + # Parse positional arguments first + if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then + DOCKER_TAG="$1" + shift + fi + + if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then + GIT_BRANCH="$1" + shift + fi + + if [[ $# -gt 0 && ! "$1" =~ ^-- ]]; then + AMBARI_GIT_URL="$1" + shift + fi + + # Parse optional arguments + while [[ $# -gt 0 ]]; do + case $1 in + --dockerfile) + DOCKERFILE="$2" + shift 2 + ;; + --no-cache) + NO_CACHE="--no-cache" + shift + ;; + --platform) + PLATFORM="--platform $2" + shift 2 + ;; + --build-arg) + BUILD_ARGS+=("--build-arg" "$2") + shift 2 + ;; + --registry) + REGISTRY="$2" + shift 2 + ;; + --username) + USERNAME="$2" + shift 2 + ;; + --password) + PASSWORD="$2" + shift 2 + ;; + --dry-run) + DRY_RUN=true + shift + ;; + --force) + FORCE=true + shift + ;; + --skip-push) + SKIP_PUSH=true + shift + ;; + --help) + show_usage + exit 0 + ;; + *) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + esac + done + + # Validate required arguments + if [[ -z "$DOCKER_TAG" ]]; then + log_error "Docker tag is required" + show_usage + exit 1 + fi +} + +# Function to display configuration +display_config() { + log_info "=== Build and Push Configuration ===" + log_info "Docker Tag: $DOCKER_TAG" + log_info "Git Branch: $GIT_BRANCH" + log_info "Ambari Git URL: $AMBARI_GIT_URL" + log_info "Dockerfile: $DOCKERFILE" + if [[ -n "$PLATFORM" ]]; then + log_info "Platform: $PLATFORM" + fi + if [[ "$SKIP_PUSH" == "false" ]]; then + log_info "Registry: $REGISTRY" + log_info "Username: ${USERNAME:-}" + log_info "Password: ${PASSWORD:+}${PASSWORD:-}" + else + log_info "Push: SKIPPED" + fi + log_info "Dry Run: $DRY_RUN" + log_info "Force: $FORCE" + log_info "=================================" +} + +# Function to build image +build_image() { + log_info "=== Building Docker Image ===" + + # Prepare build command arguments + local build_cmd_args=( + "$DOCKER_TAG" + "$GIT_BRANCH" + "$AMBARI_GIT_URL" + ) + + # Add build options + if [[ -n "$DOCKERFILE" && "$DOCKERFILE" != "Dockerfile" ]]; then + build_cmd_args+=("--dockerfile" "$DOCKERFILE") + fi + + if [[ -n "$NO_CACHE" ]]; then + build_cmd_args+=("$NO_CACHE") + fi + + if [[ -n "$PLATFORM" ]]; then + build_cmd_args+=($PLATFORM) + fi + + # Add custom build args + build_cmd_args+=("${BUILD_ARGS[@]}") + + # Execute build command + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would execute: $SCRIPT_DIR/docker-build.sh ${build_cmd_args[*]}" + return 0 + else + log_info "Executing: $SCRIPT_DIR/docker-build.sh ${build_cmd_args[*]}" + if "$SCRIPT_DIR/docker-build.sh" "${build_cmd_args[@]}"; then + log_info "Build completed successfully" + return 0 + else + log_error "Build failed" + return 1 + fi + fi +} + +# Function to push image +push_image() { + log_info "=== Pushing Docker Image ===" + + # Prepare push command arguments + local push_cmd_args=("$DOCKER_TAG") + + # Add push options + if [[ -n "$REGISTRY" && "$REGISTRY" != "docker.io" ]]; then + push_cmd_args+=("--registry" "$REGISTRY") + fi + + if [[ -n "$USERNAME" ]]; then + push_cmd_args+=("--username" "$USERNAME") + fi + + if [[ -n "$PASSWORD" ]]; then + push_cmd_args+=("--password" "$PASSWORD") + fi + + if [[ "$DRY_RUN" == "true" ]]; then + push_cmd_args+=("--dry-run") + fi + + if [[ "$FORCE" == "true" ]]; then + push_cmd_args+=("--force") + fi + + # Execute push command + log_info "Executing: $SCRIPT_DIR/docker-push.sh ${push_cmd_args[*]}" + if "$SCRIPT_DIR/docker-push.sh" "${push_cmd_args[@]}"; then + log_info "Push completed successfully" + return 0 + else + log_error "Push failed" + return 1 + fi +} + +# Function to validate prerequisites +validate_prerequisites() { + log_info "Validating prerequisites..." + + # Check if build script exists + if [[ ! -f "$SCRIPT_DIR/docker-build.sh" ]]; then + log_error "Build script not found: $SCRIPT_DIR/docker-build.sh" + exit 1 + fi + + # Check if push script exists (only if not skipping push) + if [[ "$SKIP_PUSH" == "false" && ! -f "$SCRIPT_DIR/docker-push.sh" ]]; then + log_error "Push script not found: $SCRIPT_DIR/docker-push.sh" + exit 1 + fi + + # Make sure scripts are executable + chmod +x "$SCRIPT_DIR/docker-build.sh" + if [[ "$SKIP_PUSH" == "false" ]]; then + chmod +x "$SCRIPT_DIR/docker-push.sh" + fi + + log_info "Prerequisites validation passed" +} + +# Main function +main() { + log_info "Apache Ambari Docker Build and Push Script" + log_info "==========================================" + + # Parse arguments + parse_args "$@" + + # Validate prerequisites + validate_prerequisites + + # Display configuration + display_config + + # Build image + if ! build_image; then + log_error "Build phase failed" + exit 1 + fi + + # Push image (if not skipped) + if [[ "$SKIP_PUSH" == "false" ]]; then + if ! push_image; then + log_error "Push phase failed" + exit 1 + fi + else + log_info "Push phase skipped as requested" + fi + + # Success message + log_info "" + log_info "=== Build and Push Completed Successfully ===" + log_info "Image: $DOCKER_TAG" + if [[ "$SKIP_PUSH" == "false" && "$DRY_RUN" == "false" ]]; then + log_info "Registry: $REGISTRY" + log_info "" + log_info "Next steps:" + log_info " 1. Verify image: docker pull $DOCKER_TAG" + log_info " 2. Test image: docker run -it --rm $DOCKER_TAG" + log_info " 3. Use in production deployments" + elif [[ "$DRY_RUN" == "true" ]]; then + log_info "This was a dry run - no actual changes were made" + else + log_info "Image built locally - use docker-push.sh to publish" + fi + + log_info "=============================================" +} + +# Run main function +main "$@" diff --git a/docker/images/ambari/docker-build.sh b/docker/images/ambari/docker-build.sh new file mode 100755 index 00000000000..3eb2448f6bb --- /dev/null +++ b/docker/images/ambari/docker-build.sh @@ -0,0 +1,335 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Docker Build Script +# Based on Apache Pinot's docker-build.sh approach + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default configuration +DEFAULT_DOCKER_TAG="ambari:latest" +DEFAULT_GIT_BRANCH="trunk" +DEFAULT_AMBARI_GIT_URL="https://github.com/apache/ambari.git" +DEFAULT_KAFKA_VERSION="2.0" +DEFAULT_JAVA_VERSION="8" +DEFAULT_JDK_VERSION="8" +DEFAULT_OPENJDK_IMAGE="eclipse-temurin" + +# Script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Docker Build Script + +Usage: $0 [Docker Tag] [Git Branch] [Ambari Git URL] [Kafka Version] [Java Version] [JDK Version] [OpenJDK Image] + +This script will check out Ambari Repo [Ambari Git URL] on branch [Git Branch] and build the docker image for that. +The docker image is tagged as [Docker Tag]. + +Parameters: + Docker Tag Name and tag your docker image. Default is '$DEFAULT_DOCKER_TAG'. + Git Branch The Ambari branch to build. Default is '$DEFAULT_GIT_BRANCH'. + Ambari Git URL The Ambari Git Repo to build, users can set it to their own fork. + Please note that, the URL is https:// based, not git://. + Default is the Apache Repo: '$DEFAULT_AMBARI_GIT_URL'. + Kafka Version The Kafka Version to build ambari with. Default is '$DEFAULT_KAFKA_VERSION' + Java Version The Java Build and Runtime image version. Default is '$DEFAULT_JAVA_VERSION' + JDK Version The JDK parameter to build ambari, set as part of maven build option: + -Djdk.version=\${JDK_VERSION}. Default is '$DEFAULT_JDK_VERSION' + OpenJDK Image Base image to use for Ambari build and runtime. Default is '$DEFAULT_OPENJDK_IMAGE'. + +Examples: + # Build and tag a snapshot on your own fork: + $0 ambari_fork:snapshot-3.0 snapshot-3.0 https://github.com/your_own_fork/ambari.git + + # Build a release version: + $0 ambari:release-2.7.5 release-2.7.5 https://github.com/apache/ambari.git + + # Build image with arm64 base image (for Mac M1 chips): + $0 ambari:latest trunk https://github.com/apache/ambari.git 2.0 8 8 arm64v8/openjdk + +Options: + --dockerfile DOCKERFILE Use specific Dockerfile (default: Dockerfile) + --no-cache Build without using cache + --platform PLATFORM Target platform (e.g., linux/amd64,linux/arm64) + --build-arg KEY=VALUE Pass build argument + --help Show this help message + +Environment Variables: + DOCKER_BUILDKIT Enable BuildKit (recommended: 1) + DEBUG Enable debug output (true/false) + +EOF +} + +# Function to parse arguments +parse_args() { + # Optional arguments + DOCKERFILE="Dockerfile" + NO_CACHE="" + PLATFORM="" + BUILD_ARGS=() + + # Parse all arguments, separating positional from optional + local positional_args=() + + while [[ $# -gt 0 ]]; do + case $1 in + --dockerfile) + DOCKERFILE="$2" + shift 2 + ;; + --no-cache) + NO_CACHE="--no-cache" + shift + ;; + --platform) + PLATFORM="--platform $2" + shift 2 + ;; + --build-arg) + BUILD_ARGS+=("--build-arg" "$2") + shift 2 + ;; + --help) + show_usage + exit 0 + ;; + --*) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + *) + # This is a positional argument + positional_args+=("$1") + shift + ;; + esac + done + + # Assign positional arguments + DOCKER_TAG="${positional_args[0]:-$DEFAULT_DOCKER_TAG}" + GIT_BRANCH="${positional_args[1]:-$DEFAULT_GIT_BRANCH}" + AMBARI_GIT_URL="${positional_args[2]:-$DEFAULT_AMBARI_GIT_URL}" + KAFKA_VERSION="${positional_args[3]:-$DEFAULT_KAFKA_VERSION}" + JAVA_VERSION="${positional_args[4]:-$DEFAULT_JAVA_VERSION}" + JDK_VERSION="${positional_args[5]:-$DEFAULT_JDK_VERSION}" + OPENJDK_IMAGE="${positional_args[6]:-$DEFAULT_OPENJDK_IMAGE}" +} + +# Function to validate inputs +validate_inputs() { + log_info "Validating inputs..." + + # Check if Docker is available + if ! command -v docker >/dev/null 2>&1; then + log_error "Docker is not installed or not in PATH" + exit 1 + fi + + # Check Docker daemon + if ! docker info >/dev/null 2>&1; then + log_error "Docker daemon is not running" + exit 1 + fi + + # Validate Git URL format + if [[ ! "$AMBARI_GIT_URL" =~ ^https:// ]]; then + log_error "Git URL must be https:// based: $AMBARI_GIT_URL" + exit 1 + fi + + # Check if Dockerfile exists + if [[ ! -f "$SCRIPT_DIR/$DOCKERFILE" ]]; then + log_error "Dockerfile not found: $SCRIPT_DIR/$DOCKERFILE" + exit 1 + fi + + log_info "Input validation passed" +} + +# Function to display configuration +display_config() { + log_info "=== Build Configuration ===" + log_info "Docker Tag: $DOCKER_TAG" + log_info "Git Branch: $GIT_BRANCH" + log_info "Ambari Git URL: $AMBARI_GIT_URL" + log_info "Kafka Version: $KAFKA_VERSION" + log_info "Java Version: $JAVA_VERSION" + log_info "JDK Version: $JDK_VERSION" + log_info "OpenJDK Image: $OPENJDK_IMAGE" + log_info "Dockerfile: $DOCKERFILE" + if [[ -n "$PLATFORM" ]]; then + log_info "Platform: $PLATFORM" + fi + log_info "==========================" +} + +# Function to build Docker image +build_image() { + log_info "Starting Docker build..." + + # Prepare build arguments + local build_args=( + "--build-arg" "AMBARI_GIT_URL=$AMBARI_GIT_URL" + "--build-arg" "AMBARI_BRANCH=$GIT_BRANCH" + "--build-arg" "KAFKA_VERSION=$KAFKA_VERSION" + "--build-arg" "JDK_VERSION=$JDK_VERSION" + "--build-arg" "OPENJDK_IMAGE=$OPENJDK_IMAGE" + ) + + # Add custom build args + build_args+=("${BUILD_ARGS[@]}") + + # Build command + local build_cmd=( + "docker" "build" + "${build_args[@]}" + "-f" "$SCRIPT_DIR/$DOCKERFILE" + "-t" "$DOCKER_TAG" + ) + + # Add optional flags + if [[ -n "$NO_CACHE" ]]; then + build_cmd+=("$NO_CACHE") + fi + + if [[ -n "$PLATFORM" ]]; then + build_cmd+=($PLATFORM) + fi + + # Add context (docker directory - parent of script directory) + build_cmd+=("$(dirname "$(dirname "$SCRIPT_DIR")")") + + log_debug "Build command: ${build_cmd[*]}" + + # Execute build + log_info "Executing: ${build_cmd[*]}" + if "${build_cmd[@]}"; then + log_info "Docker image built successfully: $DOCKER_TAG" + + # Display image info + log_info "Image details:" + docker images "$DOCKER_TAG" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}" + + return 0 + else + log_error "Docker build failed" + return 1 + fi +} + +# Function to run post-build tests +run_tests() { + log_info "Running post-build tests..." + + # Test if image can be run + log_info "Testing image startup..." + if docker run --rm "$DOCKER_TAG" java -version >/dev/null 2>&1; then + log_info "Image startup test passed" + else + log_warn "Image startup test failed" + fi + + # Test if required tools are available + log_info "Testing required tools..." + if docker run --rm "$DOCKER_TAG" which ambari-server >/dev/null 2>&1; then + log_info "Ambari server found in image" + else + log_warn "Ambari server not found in image" + fi +} + +# Function to cleanup +cleanup() { + log_info "Cleaning up temporary files..." + # Add any cleanup logic here if needed +} + +# Main function +main() { + log_info "Apache Ambari Docker Build Script" + log_info "=================================" + + # Parse arguments + parse_args "$@" + + # Validate inputs + validate_inputs + + # Display configuration + display_config + + # Set up cleanup trap + trap cleanup EXIT + + # Build image + if build_image; then + # Run tests + run_tests + + log_info "Build completed successfully!" + log_info "Image: $DOCKER_TAG" + + # Show next steps + log_info "" + log_info "Next steps:" + log_info " 1. Test the image: docker run -it --rm $DOCKER_TAG" + log_info " 2. Push to registry: docker push $DOCKER_TAG" + log_info " 3. Use in docker-compose or kubernetes" + + exit 0 + else + log_error "Build failed!" + exit 1 + fi +} + +# Run main function +main "$@" diff --git a/docker/images/ambari/docker-compose.yml b/docker/images/ambari/docker-compose.yml new file mode 100644 index 00000000000..8930e0ac9a7 --- /dev/null +++ b/docker/images/ambari/docker-compose.yml @@ -0,0 +1,273 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Docker Compose Configuration +# Based on Apache Pinot's docker-compose approach + +version: '3.7' + +services: + # PostgreSQL Database for Ambari + ambari-database: + image: ${POSTGRES_IMAGE:-postgres:13-alpine} + container_name: "ambari-database" + restart: unless-stopped + ports: + - "5432:5432" + environment: + POSTGRES_DB: ambari + POSTGRES_USER: ambari + POSTGRES_PASSWORD: bigdata + POSTGRES_INITDB_ARGS: "--encoding=UTF8" + volumes: + - ambari-db-data:/var/lib/postgresql/data + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ambari -d ambari"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + + # Ambari Server + ambari-server: + image: ${AMBARI_IMAGE:-apache/ambari:latest} + command: "StartServer -zkAddress ambari-zookeeper:2181" + container_name: "ambari-server" + restart: unless-stopped + ports: + - "8080:8080" # Ambari Web UI + - "8441:8441" # Ambari HTTPS + environment: + # Database configuration + AMBARI_DB_HOST: ambari-database + AMBARI_DB_PORT: 5432 + AMBARI_DB_NAME: ambari + AMBARI_DB_USER: ambari + AMBARI_DB_PASSWORD: bigdata + # Server configuration + AMBARI_COMPONENT: server + JAVA_OPTS: "-Dplugins.dir=/opt/ambari/plugins -Xms1G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-ambari-server.log" + depends_on: + ambari-database: + condition: service_healthy + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/clusters || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + volumes: + - ambari-server-data:/var/lib/ambari-server + - ambari-server-logs:/var/log/ambari-server + + # Ambari Agent (can be scaled) + ambari-agent: + image: ${AMBARI_IMAGE:-apache/ambari:latest} + command: "StartAgent -server ambari-server" + container_name: "ambari-agent" + restart: unless-stopped + environment: + # Server connection + AMBARI_SERVER_HOST: ambari-server + AMBARI_SERVER_PORT: 8080 + AMBARI_COMPONENT: agent + # Agent configuration + AGENT_HOSTNAME: ambari-agent + JAVA_OPTS: "-Xms512M -Xmx1G -XX:+UseG1GC -XX:MaxGCPauseMillis=200" + depends_on: + ambari-server: + condition: service_healthy + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "/usr/local/bin/health-check.sh"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + volumes: + - ambari-agent-data:/var/lib/ambari-agent + - ambari-agent-logs:/var/log/ambari-agent + privileged: true # Required for some agent operations + + # Ambari Metrics Collector (Optional - controlled by METRICS_ENABLED) + ambari-metrics: + image: ${AMBARI_IMAGE:-apache/ambari:latest} + command: "StartMetrics" + container_name: "ambari-metrics" + restart: unless-stopped + ports: + - "6188:6188" # Metrics Collector API + - "61888:61888" # Metrics aggregation port + environment: + # Metrics configuration + AMS_HBASE_ROOTDIR: /var/lib/ambari-metrics-collector/hbase + AMS_COLLECTOR_PORT: 6188 + AMBARI_COMPONENT: metrics + JAVA_OPTS: "-Xms1G -Xmx2G -XX:+UseG1GC -XX:MaxGCPauseMillis=200" + depends_on: + ambari-server: + condition: service_healthy + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:6188/ws/v1/timeline/metrics/metadata || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 90s + volumes: + - ambari-metrics-data:/var/lib/ambari-metrics-collector + - ambari-metrics-logs:/var/log/ambari-metrics-collector + profiles: + - metrics + deploy: + replicas: ${METRICS_ENABLED:-0} # Default to 0, meaning metrics won't start unless METRICS_ENABLED is set + + # Grafana for Metrics Visualization (Optional) + ambari-grafana: + image: grafana/grafana:10.2.0 + container_name: "ambari-grafana" + restart: unless-stopped + ports: + - "3000:3000" # Grafana Web UI + environment: + GF_SECURITY_ADMIN_PASSWORD: admin + GF_INSTALL_PLUGINS: grafana-clock-panel,grafana-simple-json-datasource + GF_USERS_ALLOW_SIGN_UP: false + GF_SERVER_ROOT_URL: http://localhost:3000 + depends_on: + - ambari-metrics + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + volumes: + - grafana-data:/var/lib/grafana + profiles: + - metrics + deploy: + replicas: ${GRAFANA_ENABLED:-0} # Default to 0, controlled by GRAFANA_ENABLED + + # Optional Zookeeper (for advanced setups) + ambari-zookeeper: + image: ${ZK_IMAGE:-zookeeper:3.8.1} + container_name: "ambari-zookeeper" + restart: unless-stopped + ports: + - "2181:2181" + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + networks: + - ambari-demo + healthcheck: + test: ["CMD", "zkServer.sh", "status"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + volumes: + - zookeeper-data:/data + - zookeeper-logs:/datalog + profiles: + - zookeeper + deploy: + replicas: ${ZOOKEEPER_ENABLED:-0} # Default to 0, controlled by ZOOKEEPER_ENABLED + + # Optional Kafka (for streaming data) + ambari-kafka: + image: ${KAFKA_IMAGE:-bitnami/kafka:3.6} + container_name: "ambari-kafka" + restart: unless-stopped + ports: + - "9092:9092" + environment: + KAFKA_ZOOKEEPER_CONNECT: ambari-zookeeper:2181/kafka + KAFKA_BROKER_ID: 0 + KAFKA_ADVERTISED_HOST_NAME: kafka + depends_on: + ambari-zookeeper: + condition: service_healthy + networks: + - ambari-demo + healthcheck: + test: ["CMD-SHELL", "kafka-broker-api-versions.sh --bootstrap-server kafka:9092"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 10s + volumes: + - kafka-data:/bitnami/kafka + profiles: + - kafka + deploy: + replicas: ${KAFKA_ENABLED:-0} # Default to 0, controlled by KAFKA_ENABLED + +# Networks +networks: + ambari-demo: + name: ambari-demo + driver: bridge + +# Volumes +volumes: + # Database + ambari-db-data: + driver: local + + # Ambari Server + ambari-server-data: + driver: local + ambari-server-logs: + driver: local + + # Ambari Agent + ambari-agent-data: + driver: local + ambari-agent-logs: + driver: local + + # Ambari Metrics (Optional) + ambari-metrics-data: + driver: local + ambari-metrics-logs: + driver: local + + # Grafana (Optional) + grafana-data: + driver: local + + # Zookeeper (Optional) + zookeeper-data: + driver: local + zookeeper-logs: + driver: local + + # Kafka (Optional) + kafka-data: + driver: local diff --git a/docker/images/ambari/docker-push.sh b/docker/images/ambari/docker-push.sh new file mode 100755 index 00000000000..6f2fd1143a0 --- /dev/null +++ b/docker/images/ambari/docker-push.sh @@ -0,0 +1,366 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Docker Push Script +# Based on Apache Pinot's docker-push.sh approach + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default configuration +DEFAULT_REGISTRY="apache" +DEFAULT_TAG="latest" + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Function to show usage +show_usage() { + cat << EOF +Apache Ambari Docker Push Script + +Usage: $0 [IMAGE_NAME] [OPTIONS] + +This script publishes a given docker image to your docker registry. +In order to push to your own repo, the image needs to be explicitly tagged with the repo name. + +Parameters: + IMAGE_NAME Docker image name with tag to push (required) + +Options: + --registry REGISTRY Docker registry URL (default: docker.io) + --username USERNAME Registry username (can also use DOCKER_USERNAME env var) + --password PASSWORD Registry password (can also use DOCKER_PASSWORD env var) + --dry-run Show what would be pushed without actually pushing + --force Force push even if image exists + --all-tags Push all tags for the repository + --help Show this help message + +Examples: + # Push to Docker Hub (apache/ambari repo): + $0 apache/ambari:latest + + # Push with custom registry: + $0 myregistry.com/ambari:latest --registry myregistry.com + + # Push with authentication: + $0 apache/ambari:latest --username myuser --password mypass + + # Dry run to see what would be pushed: + $0 apache/ambari:latest --dry-run + + # Push all tags: + $0 apache/ambari --all-tags + +Environment Variables: + DOCKER_USERNAME Registry username + DOCKER_PASSWORD Registry password + DOCKER_REGISTRY Default registry URL + DEBUG Enable debug output (true/false) + +EOF +} + +# Function to parse arguments +parse_args() { + IMAGE_NAME="" + REGISTRY="${DOCKER_REGISTRY:-docker.io}" + USERNAME="${DOCKER_USERNAME:-}" + PASSWORD="${DOCKER_PASSWORD:-}" + DRY_RUN=false + FORCE=false + ALL_TAGS=false + + while [[ $# -gt 0 ]]; do + case $1 in + --registry) + REGISTRY="$2" + shift 2 + ;; + --username) + USERNAME="$2" + shift 2 + ;; + --password) + PASSWORD="$2" + shift 2 + ;; + --dry-run) + DRY_RUN=true + shift + ;; + --force) + FORCE=true + shift + ;; + --all-tags) + ALL_TAGS=true + shift + ;; + --help) + show_usage + exit 0 + ;; + -*) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + *) + if [[ -z "$IMAGE_NAME" ]]; then + IMAGE_NAME="$1" + else + log_error "Multiple image names specified: $IMAGE_NAME and $1" + exit 1 + fi + shift + ;; + esac + done + + # Validate required arguments + if [[ -z "$IMAGE_NAME" ]]; then + log_error "Image name is required" + show_usage + exit 1 + fi +} + +# Function to validate inputs +validate_inputs() { + log_info "Validating inputs..." + + # Check if Docker is available + if ! command -v docker >/dev/null 2>&1; then + log_error "Docker is not installed or not in PATH" + exit 1 + fi + + # Check Docker daemon + if ! docker info >/dev/null 2>&1; then + log_error "Docker daemon is not running" + exit 1 + fi + + # Check if image exists locally + if [[ "$ALL_TAGS" == "false" ]]; then + if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then + log_error "Image not found locally: $IMAGE_NAME" + log_info "Available images:" + docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}" + exit 1 + fi + fi + + log_info "Input validation passed" +} + +# Function to display configuration +display_config() { + log_info "=== Push Configuration ===" + log_info "Image Name: $IMAGE_NAME" + log_info "Registry: $REGISTRY" + log_info "Username: ${USERNAME:-}" + log_info "Password: ${PASSWORD:+}${PASSWORD:-}" + log_info "Dry Run: $DRY_RUN" + log_info "Force: $FORCE" + log_info "All Tags: $ALL_TAGS" + log_info "=========================" +} + +# Function to login to registry +docker_login() { + if [[ -n "$USERNAME" && -n "$PASSWORD" ]]; then + log_info "Logging in to registry: $REGISTRY" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would login to $REGISTRY as $USERNAME" + return 0 + fi + + if echo "$PASSWORD" | docker login "$REGISTRY" --username "$USERNAME" --password-stdin; then + log_info "Successfully logged in to $REGISTRY" + else + log_error "Failed to login to $REGISTRY" + return 1 + fi + else + log_info "No credentials provided, assuming already logged in or using public registry" + fi +} + +# Function to push image +push_image() { + local image_to_push="$1" + + log_info "Pushing image: $image_to_push" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would push: $image_to_push" + return 0 + fi + + # Check if image exists on registry (unless force is used) + if [[ "$FORCE" == "false" ]]; then + log_info "Checking if image already exists on registry..." + if docker manifest inspect "$image_to_push" >/dev/null 2>&1; then + log_warn "Image already exists on registry: $image_to_push" + log_warn "Use --force to overwrite existing image" + return 1 + fi + fi + + # Push the image + if docker push "$image_to_push"; then + log_info "Successfully pushed: $image_to_push" + + # Display image info + log_info "Pushed image details:" + docker images "$image_to_push" --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}" + + return 0 + else + log_error "Failed to push: $image_to_push" + return 1 + fi +} + +# Function to push all tags +push_all_tags() { + local repo_name="${IMAGE_NAME%:*}" # Remove tag if present + + log_info "Finding all local tags for repository: $repo_name" + + # Get all local images for this repository + local images + images=$(docker images "$repo_name" --format "{{.Repository}}:{{.Tag}}" | grep -v "") + + if [[ -z "$images" ]]; then + log_error "No images found for repository: $repo_name" + return 1 + fi + + log_info "Found images to push:" + echo "$images" + + # Push each image + local failed_pushes=() + while IFS= read -r image; do + if ! push_image "$image"; then + failed_pushes+=("$image") + fi + done <<< "$images" + + # Report results + if [[ ${#failed_pushes[@]} -eq 0 ]]; then + log_info "All images pushed successfully!" + else + log_error "Failed to push images: ${failed_pushes[*]}" + return 1 + fi +} + +# Function to logout from registry +docker_logout() { + if [[ -n "$USERNAME" && "$DRY_RUN" == "false" ]]; then + log_info "Logging out from registry: $REGISTRY" + docker logout "$REGISTRY" || true + fi +} + +# Function to cleanup +cleanup() { + docker_logout +} + +# Main function +main() { + log_info "Apache Ambari Docker Push Script" + log_info "================================" + + # Parse arguments + parse_args "$@" + + # Validate inputs + validate_inputs + + # Display configuration + display_config + + # Set up cleanup trap + trap cleanup EXIT + + # Login to registry + if ! docker_login; then + log_error "Registry login failed" + exit 1 + fi + + # Push image(s) + if [[ "$ALL_TAGS" == "true" ]]; then + if push_all_tags; then + log_info "All tags pushed successfully!" + else + log_error "Some pushes failed!" + exit 1 + fi + else + if push_image "$IMAGE_NAME"; then + log_info "Image pushed successfully!" + else + log_error "Push failed!" + exit 1 + fi + fi + + # Show next steps + log_info "" + log_info "Next steps:" + log_info " 1. Verify image on registry: docker pull $IMAGE_NAME" + log_info " 2. Use in docker-compose or kubernetes" + log_info " 3. Update documentation with new image tag" + + log_info "Push completed successfully!" +} + +# Run main function +main "$@" diff --git a/docker/images/ambari/etc/ambari.properties b/docker/images/ambari/etc/ambari.properties new file mode 100644 index 00000000000..440b77dbd74 --- /dev/null +++ b/docker/images/ambari/etc/ambari.properties @@ -0,0 +1,69 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Apache Ambari Configuration Template +# This file contains default configuration values for Ambari Docker containers + +# Database Configuration +server.jdbc.driver=org.postgresql.Driver +server.jdbc.url=jdbc:postgresql://${AMBARI_DB_HOST}:${AMBARI_DB_PORT}/${AMBARI_DB_NAME} +server.jdbc.user.name=${AMBARI_DB_USER} +server.jdbc.user.passwd=${AMBARI_DB_PASSWORD} + +# Server Configuration +server.http.port=8080 +server.https.port=8441 +server.secured.url.port=8441 + +# Agent Configuration +agent.package.install.task.timeout=1800 +agent.task.timeout=900 +agent.parallel.stage.execution.enabled=true + +# Metrics Configuration (Optional) +timeline.metrics.service.default.result.limit=15840 +timeline.metrics.service.checkpointdir=/var/lib/ambari-metrics-collector/checkpoint +timeline.metrics.aggregator.checkpoint.dir=/var/lib/ambari-metrics-collector/checkpoint + +# Security Configuration +security.server.two_way_ssl=false +security.server.cert_name=ca.crt +security.server.key_name=ca.key + +# Logging Configuration +log4j.logger.org.apache.ambari=INFO +log4j.logger.org.eclipse.jetty=WARN +log4j.logger.org.springframework=WARN + +# Performance Tuning +server.connection.max.idle.millis=900000 +server.fqdn.service.url=http://169.254.169.254/latest/meta-data/public-hostname +server.stages.parallel=true + +# Views Configuration +views.dir=/var/lib/ambari-server/resources/views +views.validate=false + +# Stack Configuration +resources.dir=/var/lib/ambari-server/resources +shared.resources.dir=/usr/lib/ambari-server/lib/ambari_commons/resources + +# Custom Properties (can be overridden by environment variables) +custom.action.definitions=/var/lib/ambari-server/resources/custom_action_definitions +mpacks.staging.path=/var/lib/ambari-server/resources/mpacks diff --git a/docker/images/ambari/minimal-test.sh b/docker/images/ambari/minimal-test.sh new file mode 100755 index 00000000000..ed43345ae28 --- /dev/null +++ b/docker/images/ambari/minimal-test.sh @@ -0,0 +1,214 @@ +#!/bin/bash +# +# Minimal Test Script for Apache Ambari Docker Infrastructure +# This script tests core infrastructure components that work on ARM64 Macs +# + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_test() { + echo -e "${BLUE}[TEST]${NC} $1" +} + +# Test counter +TESTS_PASSED=0 +TESTS_FAILED=0 + +# Function to run test +run_test() { + local test_name="$1" + local test_command="$2" + + log_test "Running: $test_name" + + if eval "$test_command" >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} PASSED: $test_name" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo -e " ${RED}✗${NC} FAILED: $test_name" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi +} + +# Function to check HTTP endpoint +check_http() { + local url="$1" + local expected_status="${2:-200}" + + local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000") + + if [[ "$status" == "$expected_status" ]]; then + return 0 + else + return 1 + fi +} + +# Main test function +main() { + log_info "=== Apache Ambari Docker Minimal Infrastructure Test ===" + log_info "Testing core infrastructure components (ARM64 compatible)..." + + # Test 1: Check Docker is running + run_test "Docker daemon running" "docker info" + + # Test 2: Check Docker Compose is available + run_test "Docker Compose available" "docker-compose --version" + + # Test 3: Check if we're in the right directory + run_test "In Ambari project directory" "test -f pom.xml && test -d docker" + + # Test 4: Start minimal infrastructure services + log_info "Starting minimal infrastructure services..." + docker-compose -f docker/docker-compose.minimal.yml up -d + + # Wait for services to start + log_info "Waiting for services to start (30 seconds)..." + sleep 30 + + # Test 5: Check if containers are running + run_test "Database container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-database.*Up'" + run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-zookeeper.*Up'" + run_test "Grafana container running" "docker-compose -f docker/docker-compose.minimal.yml ps | grep -q 'ambari-grafana-test.*Up'" + + # Test 6: Check HTTP endpoints + run_test "Grafana accessible" "check_http 'http://localhost:3002'" + + # Test 7: Check API endpoints + run_test "Grafana API responding" "curl -s http://localhost:3002/api/health | grep -q 'database'" + + # Test 8: Check database connectivity + run_test "Database accessible" "docker-compose -f docker/docker-compose.minimal.yml exec -T ambari-db pg_isready -U ambari" + + # Test 9: Check Zookeeper + run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2182 | grep -q 'imok'" + + # Test 10: Check database operations + run_test "Database operations working" "docker-compose -f docker/docker-compose.minimal.yml exec -T ambari-db psql -U ambari -d ambari -c 'SELECT COUNT(*) FROM users;' | grep -q '1'" + + # Summary + log_info "=== Test Results ===" + log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}" + log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}" + + if [[ $TESTS_FAILED -eq 0 ]]; then + log_info "${GREEN}🎉 All minimal infrastructure tests passed!${NC}" + log_info "" + log_info "Core infrastructure is ready. You can now:" + log_info "1. Access Grafana: http://localhost:3002 (admin/admin)" + log_info "2. Connect to database: docker-compose -f docker/docker-compose.minimal.yml exec ambari-db psql -U ambari -d ambari" + log_info "3. Connect to Zookeeper: echo 'ls /' | nc localhost 2182" + log_info "" + log_info "Database contains:" + log_info "- Admin user (admin/admin)" + log_info "- Sample development cluster" + log_info "- Ambari schema tables" + log_info "" + log_info "To stop services: docker-compose -f docker/docker-compose.minimal.yml down" + return 0 + else + log_error "❌ Some tests failed. Please check the logs and troubleshoot." + log_info "" + log_info "Troubleshooting steps:" + log_info "1. Check container logs: docker-compose -f docker/docker-compose.minimal.yml logs" + log_info "2. Check container status: docker-compose -f docker/docker-compose.minimal.yml ps" + log_info "3. Restart services: docker-compose -f docker/docker-compose.minimal.yml restart" + return 1 + fi +} + +# Help function +show_help() { + cat << EOF +Apache Ambari Docker Minimal Infrastructure Test Script + +Usage: $0 [OPTIONS] + +Options: + -h, --help Show this help message + -v, --verbose Enable verbose output + --stop Stop services after testing + --clean Clean up volumes after testing + +Examples: + $0 # Run minimal infrastructure tests + $0 --stop # Run tests and stop services + $0 --clean # Run tests and clean up everything + +EOF +} + +# Parse command line arguments +VERBOSE=false +STOP_SERVICES=false +CLEAN_UP=false + +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_help + exit 0 + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + --stop) + STOP_SERVICES=true + shift + ;; + --clean) + CLEAN_UP=true + shift + ;; + *) + log_error "Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +# Enable verbose mode if requested +if [[ "$VERBOSE" == "true" ]]; then + set -x +fi + +# Run main tests +main +exit_code=$? + +# Stop services if requested +if [[ "$STOP_SERVICES" == "true" ]]; then + log_info "Stopping Docker services..." + docker-compose -f docker/docker-compose.minimal.yml down +fi + +# Clean up if requested +if [[ "$CLEAN_UP" == "true" ]]; then + log_info "Cleaning up volumes and networks..." + docker-compose -f docker/docker-compose.minimal.yml down -v + docker system prune -f +fi + +exit $exit_code diff --git a/docker/images/ambari/quick-test.sh b/docker/images/ambari/quick-test.sh new file mode 100755 index 00000000000..06cfbd85680 --- /dev/null +++ b/docker/images/ambari/quick-test.sh @@ -0,0 +1,225 @@ +#!/bin/bash +# +# Quick Test Script for Apache Ambari Docker Setup +# This script performs basic verification of the Ambari Docker environment +# + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_test() { + echo -e "${BLUE}[TEST]${NC} $1" +} + +# Test counter +TESTS_PASSED=0 +TESTS_FAILED=0 + +# Function to run test +run_test() { + local test_name="$1" + local test_command="$2" + + log_test "Running: $test_name" + + if eval "$test_command" >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} PASSED: $test_name" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo -e " ${RED}✗${NC} FAILED: $test_name" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi +} + +# Function to check HTTP endpoint +check_http() { + local url="$1" + local expected_status="${2:-200}" + + local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000") + + if [[ "$status" == "$expected_status" ]]; then + return 0 + else + return 1 + fi +} + +# Main test function +main() { + log_info "=== Apache Ambari Docker Quick Test ===" + log_info "Starting basic verification tests..." + + # Test 1: Check Docker is running + run_test "Docker daemon running" "docker info" + + # Test 2: Check Docker Compose is available + run_test "Docker Compose available" "docker-compose --version" + + # Test 3: Check if we're in the right directory + run_test "In Ambari project directory" "test -f pom.xml && test -d docker" + + # Test 4: Check if images exist + run_test "Ambari server image exists" "docker images | grep -q 'apache/ambari-server'" + run_test "Ambari agent image exists" "docker images | grep -q 'apache/ambari-agent'" + run_test "Ambari metrics image exists" "docker images | grep -q 'apache/ambari-metrics'" + + # Test 5: Check if containers are running + run_test "Ambari server container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-server.*Up'" + run_test "Ambari database container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-database.*Up'" + run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.yml ps | grep -q 'ambari-zookeeper.*Up'" + + # Test 6: Check HTTP endpoints + run_test "Ambari Web UI accessible" "check_http 'http://localhost:8080'" + run_test "Grafana accessible" "check_http 'http://localhost:3000'" + run_test "NameNode UI accessible" "check_http 'http://localhost:9870'" + run_test "ResourceManager UI accessible" "check_http 'http://localhost:8088'" + + # Test 7: Check API endpoints + run_test "Ambari API responding" "curl -s -u admin:admin http://localhost:8080/api/v1/version | grep -q 'version'" + run_test "Metrics API responding" "curl -s http://localhost:6188/ws/v1/timeline/metrics/metadata | grep -q 'metadata'" + run_test "Grafana API responding" "curl -s http://localhost:3000/api/health | grep -q 'database'" + + # Test 8: Check database connectivity + run_test "Database accessible" "docker-compose -f docker/docker-compose.yml exec -T ambari-db pg_isready -U ambari" + + # Test 9: Check Zookeeper + run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2181 | grep -q 'imok'" + + # Test 10: Check agent registration + run_test "Agent registered" "curl -s -u admin:admin http://localhost:8080/api/v1/hosts | grep -q 'host_name'" + + # Summary + log_info "=== Test Results ===" + log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}" + log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}" + + if [[ $TESTS_FAILED -eq 0 ]]; then + log_info "${GREEN}🎉 All tests passed! Ambari Docker setup is working correctly.${NC}" + log_info "" + log_info "Next steps:" + log_info "1. Access Ambari Web UI: http://localhost:8080 (admin/admin)" + log_info "2. Access Grafana: http://localhost:3000 (admin/admin)" + log_info "3. Check Hadoop NameNode: http://localhost:9870" + log_info "4. Check YARN ResourceManager: http://localhost:8088" + return 0 + else + log_error "❌ Some tests failed. Please check the logs and troubleshoot." + log_info "" + log_info "Troubleshooting steps:" + log_info "1. Check container logs: docker-compose -f docker/docker-compose.yml logs" + log_info "2. Check container status: docker-compose -f docker/docker-compose.yml ps" + log_info "3. Restart services: docker-compose -f docker/docker-compose.yml restart" + log_info "4. See full testing guide: docker/TESTING.md" + return 1 + fi +} + +# Help function +show_help() { + cat << EOF +Apache Ambari Docker Quick Test Script + +Usage: $0 [OPTIONS] + +Options: + -h, --help Show this help message + -v, --verbose Enable verbose output + --build Build images before testing + --start Start services before testing + --stop Stop services after testing + +Examples: + $0 # Run basic tests + $0 --build --start # Build images, start services, then test + $0 -v # Run tests with verbose output + +EOF +} + +# Parse command line arguments +VERBOSE=false +BUILD_IMAGES=false +START_SERVICES=false +STOP_SERVICES=false + +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_help + exit 0 + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + --build) + BUILD_IMAGES=true + shift + ;; + --start) + START_SERVICES=true + shift + ;; + --stop) + STOP_SERVICES=true + shift + ;; + *) + log_error "Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +# Enable verbose mode if requested +if [[ "$VERBOSE" == "true" ]]; then + set -x +fi + +# Build images if requested +if [[ "$BUILD_IMAGES" == "true" ]]; then + log_info "Building Docker images..." + ./docker/build.sh all +fi + +# Start services if requested +if [[ "$START_SERVICES" == "true" ]]; then + log_info "Starting Docker services..." + docker-compose -f docker/docker-compose.yml up -d + + log_info "Waiting for services to start (60 seconds)..." + sleep 60 +fi + +# Run main tests +main +exit_code=$? + +# Stop services if requested +if [[ "$STOP_SERVICES" == "true" ]]; then + log_info "Stopping Docker services..." + docker-compose -f docker/docker-compose.yml down +fi + +exit $exit_code diff --git a/docker/images/ambari/simple-test.sh b/docker/images/ambari/simple-test.sh new file mode 100755 index 00000000000..ba6e18edf9d --- /dev/null +++ b/docker/images/ambari/simple-test.sh @@ -0,0 +1,217 @@ +#!/bin/bash +# +# Simple Test Script for Apache Ambari Docker Infrastructure +# This script tests the supporting infrastructure without building Ambari from source +# + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_test() { + echo -e "${BLUE}[TEST]${NC} $1" +} + +# Test counter +TESTS_PASSED=0 +TESTS_FAILED=0 + +# Function to run test +run_test() { + local test_name="$1" + local test_command="$2" + + log_test "Running: $test_name" + + if eval "$test_command" >/dev/null 2>&1; then + echo -e " ${GREEN}✓${NC} PASSED: $test_name" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo -e " ${RED}✗${NC} FAILED: $test_name" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi +} + +# Function to check HTTP endpoint +check_http() { + local url="$1" + local expected_status="${2:-200}" + + local status=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000") + + if [[ "$status" == "$expected_status" ]]; then + return 0 + else + return 1 + fi +} + +# Main test function +main() { + log_info "=== Apache Ambari Docker Infrastructure Test ===" + log_info "Testing supporting infrastructure components..." + + # Test 1: Check Docker is running + run_test "Docker daemon running" "docker info" + + # Test 2: Check Docker Compose is available + run_test "Docker Compose available" "docker-compose --version" + + # Test 3: Check if we're in the right directory + run_test "In Ambari project directory" "test -f pom.xml && test -d docker" + + # Test 4: Start infrastructure services + log_info "Starting infrastructure services..." + docker-compose -f docker/docker-compose.simple.yml up -d + + # Wait for services to start + log_info "Waiting for services to start (60 seconds)..." + sleep 60 + + # Test 5: Check if containers are running + run_test "Database container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-database.*Up'" + run_test "Zookeeper container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-zookeeper.*Up'" + run_test "NameNode container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-namenode.*Up'" + run_test "DataNode container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-datanode.*Up'" + run_test "ResourceManager container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'hadoop-resourcemanager.*Up'" + run_test "Grafana container running" "docker-compose -f docker/docker-compose.simple.yml ps | grep -q 'ambari-grafana.*Up'" + + # Test 6: Check HTTP endpoints + run_test "Grafana accessible" "check_http 'http://localhost:3001'" + run_test "NameNode UI accessible" "check_http 'http://localhost:9870'" + run_test "DataNode UI accessible" "check_http 'http://localhost:9864'" + run_test "ResourceManager UI accessible" "check_http 'http://localhost:8088'" + + # Test 7: Check API endpoints + run_test "Grafana API responding" "curl -s http://localhost:3001/api/health | grep -q 'database'" + + # Test 8: Check database connectivity + run_test "Database accessible" "docker-compose -f docker/docker-compose.simple.yml exec -T ambari-db pg_isready -U ambari" + + # Test 9: Check Zookeeper + run_test "Zookeeper accessible" "echo 'ruok' | nc localhost 2181 | grep -q 'imok'" + + # Test 10: Check HDFS operations + run_test "HDFS operations working" "docker-compose -f docker/docker-compose.simple.yml exec namenode hdfs dfs -mkdir -p /test && docker-compose -f docker/docker-compose.simple.yml exec namenode hdfs dfs -ls / | grep -q test" + + # Summary + log_info "=== Test Results ===" + log_info "Tests Passed: ${GREEN}$TESTS_PASSED${NC}" + log_info "Tests Failed: ${RED}$TESTS_FAILED${NC}" + + if [[ $TESTS_FAILED -eq 0 ]]; then + log_info "${GREEN}🎉 All infrastructure tests passed!${NC}" + log_info "" + log_info "Infrastructure is ready. You can now:" + log_info "1. Access Grafana: http://localhost:3001 (admin/admin)" + log_info "2. Check Hadoop NameNode: http://localhost:9870" + log_info "3. Check DataNode: http://localhost:9864" + log_info "4. Check YARN ResourceManager: http://localhost:8088" + log_info "5. Connect to database: docker-compose -f docker/docker-compose.simple.yml exec ambari-db psql -U ambari -d ambari" + log_info "" + log_info "To stop services: docker-compose -f docker/docker-compose.simple.yml down" + return 0 + else + log_error "❌ Some tests failed. Please check the logs and troubleshoot." + log_info "" + log_info "Troubleshooting steps:" + log_info "1. Check container logs: docker-compose -f docker/docker-compose.simple.yml logs" + log_info "2. Check container status: docker-compose -f docker/docker-compose.simple.yml ps" + log_info "3. Restart services: docker-compose -f docker/docker-compose.simple.yml restart" + return 1 + fi +} + +# Help function +show_help() { + cat << EOF +Apache Ambari Docker Infrastructure Test Script + +Usage: $0 [OPTIONS] + +Options: + -h, --help Show this help message + -v, --verbose Enable verbose output + --stop Stop services after testing + --clean Clean up volumes after testing + +Examples: + $0 # Run infrastructure tests + $0 --stop # Run tests and stop services + $0 --clean # Run tests and clean up everything + +EOF +} + +# Parse command line arguments +VERBOSE=false +STOP_SERVICES=false +CLEAN_UP=false + +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_help + exit 0 + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + --stop) + STOP_SERVICES=true + shift + ;; + --clean) + CLEAN_UP=true + shift + ;; + *) + log_error "Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +# Enable verbose mode if requested +if [[ "$VERBOSE" == "true" ]]; then + set -x +fi + +# Run main tests +main +exit_code=$? + +# Stop services if requested +if [[ "$STOP_SERVICES" == "true" ]]; then + log_info "Stopping Docker services..." + docker-compose -f docker/docker-compose.simple.yml down +fi + +# Clean up if requested +if [[ "$CLEAN_UP" == "true" ]]; then + log_info "Cleaning up volumes and networks..." + docker-compose -f docker/docker-compose.simple.yml down -v + docker system prune -f +fi + +exit $exit_code diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh new file mode 100644 index 00000000000..f1558703625 --- /dev/null +++ b/docker/scripts/entrypoint.sh @@ -0,0 +1,256 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_debug() { + if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then + echo -e "${BLUE}[DEBUG]${NC} $1" + fi +} + +# Default environment variables +export AMBARI_USER=${AMBARI_USER:-ambari} +export AMBARI_HOME=${AMBARI_HOME:-/opt/ambari} +export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64} +export MAVEN_HOME=${MAVEN_HOME:-/opt/maven} +export PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${PATH} + +# Database configuration +export AMBARI_DB_HOST=${AMBARI_DB_HOST:-ambari-db} +export AMBARI_DB_PORT=${AMBARI_DB_PORT:-5432} +export AMBARI_DB_NAME=${AMBARI_DB_NAME:-ambari} +export AMBARI_DB_USER=${AMBARI_DB_USER:-ambari} +export AMBARI_DB_PASSWORD=${AMBARI_DB_PASSWORD:-bigdata} + +# Server configuration +export AMBARI_SERVER_HOST=${AMBARI_SERVER_HOST:-localhost} +export AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080} +export AMBARI_SERVER_HTTPS=${AMBARI_SERVER_HTTPS:-false} + +# Agent configuration +export AGENT_HOSTNAME=${AGENT_HOSTNAME:-$(hostname -f)} + +# Metrics configuration +export AMS_HBASE_ROOTDIR=${AMS_HBASE_ROOTDIR:-/var/lib/ambari-metrics-collector/hbase} +export AMS_COLLECTOR_PORT=${AMS_COLLECTOR_PORT:-6188} +export AMS_GRAFANA_ENABLED=${AMS_GRAFANA_ENABLED:-true} + +# JVM configuration +export JAVA_OPTS=${JAVA_OPTS:-"-Xmx2g -Xms1g -XX:+UseG1GC"} +export AMS_JAVA_OPTS=${AMS_JAVA_OPTS:-"-Xmx1g -Xms512m"} + +# Debug configuration +if [[ "${AMBARI_DEBUG:-false}" == "true" ]]; then + export JAVA_OPTS="${JAVA_OPTS} -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" + log_info "Debug mode enabled. Java debug port: 5005" +fi + +# Function to wait for service +wait_for_service() { + local host=$1 + local port=$2 + local service_name=$3 + local timeout=${4:-60} + + log_info "Waiting for ${service_name} at ${host}:${port}..." + + local count=0 + while ! nc -z "${host}" "${port}" >/dev/null 2>&1; do + if [ ${count} -ge ${timeout} ]; then + log_error "Timeout waiting for ${service_name} at ${host}:${port}" + return 1 + fi + count=$((count + 1)) + sleep 1 + done + + log_info "${service_name} is available at ${host}:${port}" + return 0 +} + +# Function to wait for database +wait_for_database() { + if [[ "${AMBARI_DB_HOST}" != "localhost" && "${AMBARI_DB_HOST}" != "127.0.0.1" ]]; then + wait_for_service "${AMBARI_DB_HOST}" "${AMBARI_DB_PORT}" "Database" 120 + fi +} + +# Function to setup directories and permissions +setup_directories() { + log_info "Setting up directories and permissions..." + + # Ensure directories exist and have correct permissions + local dirs=( + "/var/log/ambari-server" + "/var/log/ambari-agent" + "/var/log/ambari-metrics-collector" + "/var/log/ambari-metrics-monitor" + "/var/run/ambari-server" + "/var/run/ambari-agent" + "/var/run/ambari-metrics-collector" + "/var/run/ambari-metrics-monitor" + "/var/lib/ambari-server" + "/var/lib/ambari-agent" + "/var/lib/ambari-metrics-collector" + "/etc/ambari-server/conf" + "/etc/ambari-agent/conf" + "/etc/ambari-metrics-collector/conf" + "/etc/ambari-metrics-monitor/conf" + ) + + for dir in "${dirs[@]}"; do + if [[ ! -d "${dir}" ]]; then + sudo mkdir -p "${dir}" + fi + sudo chown -R ${AMBARI_USER}:${AMBARI_USER} "${dir}" + done +} + +# Function to setup SSH +setup_ssh() { + log_info "Setting up SSH configuration..." + + # Start SSH daemon if not running + if ! pgrep -x "sshd" > /dev/null; then + sudo service ssh start || sudo /usr/sbin/sshd + fi + + # Ensure SSH keys are properly configured + if [[ ! -f "/home/${AMBARI_USER}/.ssh/id_rsa" ]]; then + ssh-keygen -t rsa -N '' -f "/home/${AMBARI_USER}/.ssh/id_rsa" + cat "/home/${AMBARI_USER}/.ssh/id_rsa.pub" >> "/home/${AMBARI_USER}/.ssh/authorized_keys" + chmod 600 "/home/${AMBARI_USER}/.ssh/authorized_keys" + chmod 700 "/home/${AMBARI_USER}/.ssh" + fi +} + +# Function to setup time synchronization +setup_time_sync() { + log_info "Setting up time synchronization..." + + # Start NTP service if available + if command -v ntpd >/dev/null 2>&1; then + sudo service ntp start || true + fi + + # Sync time once + sudo ntpdate -s time.nist.gov || true +} + +# Function to display environment info +display_environment_info() { + log_info "=== Ambari Docker Environment ===" + log_info "Java Version: $(java -version 2>&1 | head -n 1)" + log_info "Maven Version: $(mvn -version 2>&1 | head -n 1)" + log_info "Node.js Version: $(node --version 2>/dev/null || echo 'Not installed')" + log_info "Python Version: $(python3 --version)" + log_info "User: $(whoami)" + log_info "Working Directory: $(pwd)" + log_info "JAVA_HOME: ${JAVA_HOME}" + log_info "MAVEN_HOME: ${MAVEN_HOME}" + log_info "=================================" +} + +# Function to handle signals +cleanup() { + log_info "Received shutdown signal, cleaning up..." + + # Stop any running Ambari services + if pgrep -f "ambari-server" > /dev/null; then + log_info "Stopping Ambari Server..." + sudo ambari-server stop || true + fi + + if pgrep -f "ambari-agent" > /dev/null; then + log_info "Stopping Ambari Agent..." + sudo ambari-agent stop || true + fi + + if pgrep -f "ambari-metrics-collector" > /dev/null; then + log_info "Stopping Ambari Metrics Collector..." + sudo ambari-metrics-collector stop || true + fi + + if pgrep -f "ambari-metrics-monitor" > /dev/null; then + log_info "Stopping Ambari Metrics Monitor..." + sudo ambari-metrics-monitor stop || true + fi + + log_info "Cleanup completed" + exit 0 +} + +# Set up signal handlers +trap cleanup SIGTERM SIGINT SIGQUIT + +# Main initialization +main() { + log_info "Starting Ambari Docker container initialization..." + + # Display environment information + display_environment_info + + # Setup basic requirements + setup_directories + setup_ssh + setup_time_sync + + # Wait for dependencies if needed + if [[ "${1}" == "ambari-server" || "${1}" == "server" ]]; then + wait_for_database + elif [[ "${1}" == "ambari-agent" || "${1}" == "agent" ]]; then + wait_for_service "${AMBARI_SERVER_HOST}" "${AMBARI_SERVER_PORT}" "Ambari Server" 300 + fi + + log_info "Container initialization completed successfully" + + # Execute the command + if [[ $# -eq 0 ]]; then + log_info "No command specified, starting interactive shell" + exec /bin/bash + else + log_info "Executing command: $*" + exec "$@" + fi +} + +# Run main function +main "$@" diff --git a/docker/scripts/health-check.sh b/docker/scripts/health-check.sh new file mode 100644 index 00000000000..9d2a1d40fca --- /dev/null +++ b/docker/scripts/health-check.sh @@ -0,0 +1,329 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# Health check script for Ambari Docker containers +# This script determines the container type and performs appropriate health checks + +set -e + +# Configuration +AMBARI_SERVER_PORT=${AMBARI_SERVER_PORT:-8080} +AMBARI_SERVER_SSL_PORT=${AMBARI_SERVER_SSL_PORT:-8441} +AMS_COLLECTOR_PORT=${AMS_COLLECTOR_PORT:-6188} +GRAFANA_PORT=${GRAFANA_PORT:-3000} + +# Timeout for HTTP requests (seconds) +HTTP_TIMEOUT=10 + +# Function to check HTTP endpoint +check_http() { + local url=$1 + local expected_status=${2:-200} + local timeout=${3:-$HTTP_TIMEOUT} + + local response + response=$(curl -s -o /dev/null -w "%{http_code}" --max-time "$timeout" "$url" 2>/dev/null || echo "000") + + if [[ "$response" == "$expected_status" ]]; then + return 0 + else + echo "HTTP check failed for $url (got $response, expected $expected_status)" + return 1 + fi +} + +# Function to check if process is running +check_process() { + local process_name=$1 + if pgrep -f "$process_name" > /dev/null; then + return 0 + else + echo "Process check failed: $process_name not running" + return 1 + fi +} + +# Function to check if port is listening +check_port() { + local port=$1 + local host=${2:-localhost} + + if nc -z "$host" "$port" 2>/dev/null; then + return 0 + else + echo "Port check failed: $host:$port not accessible" + return 1 + fi +} + +# Function to check file exists and is readable +check_file() { + local file_path=$1 + if [[ -r "$file_path" ]]; then + return 0 + else + echo "File check failed: $file_path not readable" + return 1 + fi +} + +# Function to check Ambari Server health +check_ambari_server() { + echo "Checking Ambari Server health..." + + # Check if server process is running + if ! check_process "ambari-server"; then + return 1 + fi + + # Check if server port is listening + if ! check_port "$AMBARI_SERVER_PORT"; then + return 1 + fi + + # Check server API endpoint + local server_url="http://localhost:$AMBARI_SERVER_PORT/api/v1/clusters" + if ! check_http "$server_url" "200"; then + # Try with authentication (default admin:admin) + server_url="http://admin:admin@localhost:$AMBARI_SERVER_PORT/api/v1/clusters" + if ! check_http "$server_url" "200"; then + return 1 + fi + fi + + # Check server log file exists + if ! check_file "/var/log/ambari-server/ambari-server.log"; then + return 1 + fi + + echo "Ambari Server health check passed" + return 0 +} + +# Function to check Ambari Agent health +check_ambari_agent() { + echo "Checking Ambari Agent health..." + + # Check if agent process is running + if ! check_process "ambari-agent"; then + return 1 + fi + + # Check agent log file exists + if ! check_file "/var/log/ambari-agent/ambari-agent.log"; then + return 1 + fi + + # Check if agent can communicate with server (if server host is set) + if [[ -n "${AMBARI_SERVER_HOST:-}" && "${AMBARI_SERVER_HOST}" != "localhost" ]]; then + if ! check_port "$AMBARI_SERVER_PORT" "$AMBARI_SERVER_HOST"; then + echo "Warning: Cannot reach Ambari Server at $AMBARI_SERVER_HOST:$AMBARI_SERVER_PORT" + # Don't fail health check for this, as server might be starting + fi + fi + + echo "Ambari Agent health check passed" + return 0 +} + +# Function to check Ambari Metrics Collector health +check_ambari_metrics() { + echo "Checking Ambari Metrics Collector health..." + + # Check if metrics collector process is running + if ! check_process "ambari-metrics-collector"; then + return 1 + fi + + # Check if collector port is listening + if ! check_port "$AMS_COLLECTOR_PORT"; then + return 1 + fi + + # Check metrics API endpoint + local metrics_url="http://localhost:$AMS_COLLECTOR_PORT/ws/v1/timeline/metrics/metadata" + if ! check_http "$metrics_url" "200"; then + return 1 + fi + + # Check HBase master process (embedded in metrics collector) + if ! check_process "HMaster"; then + echo "Warning: HBase Master process not found" + # Don't fail for this as it might be starting + fi + + # Check collector log file exists + if ! check_file "/var/log/ambari-metrics-collector/ambari-metrics-collector.log"; then + return 1 + fi + + echo "Ambari Metrics Collector health check passed" + return 0 +} + +# Function to check Grafana health +check_grafana() { + echo "Checking Grafana health..." + + # Check if Grafana process is running + if ! check_process "grafana-server"; then + return 1 + fi + + # Check if Grafana port is listening + if ! check_port "$GRAFANA_PORT"; then + return 1 + fi + + # Check Grafana API endpoint + local grafana_url="http://localhost:$GRAFANA_PORT/api/health" + if ! check_http "$grafana_url" "200"; then + return 1 + fi + + echo "Grafana health check passed" + return 0 +} + +# Function to check database connectivity +check_database() { + echo "Checking database connectivity..." + + local db_host=${AMBARI_DB_HOST:-localhost} + local db_port=${AMBARI_DB_PORT:-5432} + local db_name=${AMBARI_DB_NAME:-ambari} + local db_user=${AMBARI_DB_USER:-ambari} + + # Check if database port is accessible + if ! check_port "$db_port" "$db_host"; then + return 1 + fi + + # Try to connect to database (if PostgreSQL client is available) + if command -v psql >/dev/null 2>&1; then + if ! PGPASSWORD="${AMBARI_DB_PASSWORD}" psql -h "$db_host" -p "$db_port" -U "$db_user" -d "$db_name" -c "SELECT 1;" >/dev/null 2>&1; then + echo "Database connection test failed" + return 1 + fi + fi + + echo "Database connectivity check passed" + return 0 +} + +# Function to perform basic system health checks +check_system() { + echo "Checking system health..." + + # Check disk space (warn if less than 1GB free) + local free_space + free_space=$(df / | awk 'NR==2 {print $4}') + if [[ "$free_space" -lt 1048576 ]]; then # 1GB in KB + echo "Warning: Low disk space ($(($free_space / 1024))MB free)" + fi + + # Check memory usage (warn if less than 512MB free) + local free_memory + free_memory=$(free | awk 'NR==2{printf "%.0f", $7/1024}') + if [[ "$free_memory" -lt 512 ]]; then + echo "Warning: Low memory (${free_memory}MB free)" + fi + + # Check if Java is available + if ! command -v java >/dev/null 2>&1; then + echo "Java not found in PATH" + return 1 + fi + + echo "System health check passed" + return 0 +} + +# Main health check function +main() { + local exit_code=0 + + echo "=== Ambari Docker Health Check ===" + echo "Timestamp: $(date)" + echo "Hostname: $(hostname)" + echo "Container ID: $(hostname)" + + # Always check system health + if ! check_system; then + exit_code=1 + fi + + # Determine container type and run appropriate checks + # Check based on running processes and environment variables + + if pgrep -f "ambari-server" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "server" ]]; then + if ! check_ambari_server; then + exit_code=1 + fi + + # If this is a server container, also check database + if ! check_database; then + exit_code=1 + fi + fi + + if pgrep -f "ambari-agent" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "agent" ]]; then + if ! check_ambari_agent; then + exit_code=1 + fi + fi + + if pgrep -f "ambari-metrics-collector" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "metrics" ]]; then + if ! check_ambari_metrics; then + exit_code=1 + fi + fi + + if pgrep -f "grafana-server" > /dev/null || [[ "${AMBARI_COMPONENT:-}" == "grafana" ]]; then + if ! check_grafana; then + exit_code=1 + fi + fi + + # If no specific component is detected, this might be a base container + if ! pgrep -f "ambari-" > /dev/null && ! pgrep -f "grafana-server" > /dev/null; then + echo "No Ambari services detected - assuming base container" + # For base containers, just check that basic tools are available + if ! command -v java >/dev/null 2>&1 || ! command -v mvn >/dev/null 2>&1; then + echo "Basic tools (Java/Maven) not available" + exit_code=1 + else + echo "Base container health check passed" + fi + fi + + echo "=== Health Check Complete ===" + + if [[ $exit_code -eq 0 ]]; then + echo "Status: HEALTHY" + else + echo "Status: UNHEALTHY" + fi + + exit $exit_code +} + +# Run main function +main "$@" diff --git a/docker/scripts/init-db.sql b/docker/scripts/init-db.sql new file mode 100644 index 00000000000..13ca74df1f7 --- /dev/null +++ b/docker/scripts/init-db.sql @@ -0,0 +1,401 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. +-- + +-- Apache Ambari Database Initialization Script for PostgreSQL +-- This script initializes the Ambari database with required schemas and data + +\echo 'Initializing Ambari database...' + +-- Set client encoding +SET client_encoding = 'UTF8'; + +-- Create additional databases if needed +-- CREATE DATABASE ambari_metrics OWNER ambari; + +-- Connect to ambari database +\c ambari; + +-- Set search path +SET search_path = public; + +-- Create extensions if available +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +CREATE EXTENSION IF NOT EXISTS "pgcrypto"; + +-- Create basic tables for Ambari (simplified schema for Docker setup) +-- Note: The full schema will be created by Ambari Server setup process + +-- Users table +CREATE TABLE IF NOT EXISTS users ( + user_id SERIAL PRIMARY KEY, + user_name VARCHAR(255) NOT NULL UNIQUE, + user_password VARCHAR(255), + user_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL', + ldap_user BOOLEAN NOT NULL DEFAULT FALSE, + user_active BOOLEAN NOT NULL DEFAULT TRUE, + admin BOOLEAN NOT NULL DEFAULT FALSE, + created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + modified_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- Insert default admin user (password: admin) +INSERT INTO users (user_name, user_password, user_type, ldap_user, user_active, admin) +VALUES ('admin', 'c7063d9d94f7ac7d8c6e6d3b429c7c8d', 'LOCAL', FALSE, TRUE, TRUE) +ON CONFLICT (user_name) DO NOTHING; + +-- Clusters table +CREATE TABLE IF NOT EXISTS clusters ( + cluster_id BIGSERIAL PRIMARY KEY, + cluster_name VARCHAR(255) NOT NULL UNIQUE, + cluster_info VARCHAR(255) NOT NULL DEFAULT 'Ambari', + desired_cluster_state VARCHAR(255) NOT NULL DEFAULT 'INIT', + desired_stack_version VARCHAR(255) NOT NULL DEFAULT '{"stackName":"HDP","stackVersion":"2.6"}', + cluster_state VARCHAR(255) NOT NULL DEFAULT 'INIT', + provisioning_state VARCHAR(255) NOT NULL DEFAULT 'INIT', + security_type VARCHAR(255) NOT NULL DEFAULT 'NONE', + version VARCHAR(255) NOT NULL DEFAULT '1.0.0' +); + +-- Hosts table +CREATE TABLE IF NOT EXISTS hosts ( + host_id BIGSERIAL PRIMARY KEY, + host_name VARCHAR(255) NOT NULL UNIQUE, + cpu_count INTEGER NOT NULL DEFAULT 1, + cpu_info VARCHAR(255) NOT NULL DEFAULT 'Unknown', + discovery_status VARCHAR(2000) NOT NULL DEFAULT 'PENDING', + host_attributes TEXT, + ipv4 VARCHAR(255), + ipv6 VARCHAR(255), + last_registration_time BIGINT, + os_arch VARCHAR(255) NOT NULL DEFAULT 'x86_64', + os_info VARCHAR(1000) NOT NULL DEFAULT 'Unknown', + os_type VARCHAR(255) NOT NULL DEFAULT 'Unknown', + ph_cpu_count INTEGER, + public_host_name VARCHAR(255), + rack_info VARCHAR(255) NOT NULL DEFAULT '/default-rack', + total_mem BIGINT NOT NULL DEFAULT 0 +); + +-- Services table +CREATE TABLE IF NOT EXISTS clusterservices ( + service_name VARCHAR(255) NOT NULL, + cluster_id BIGINT NOT NULL, + service_enabled INTEGER NOT NULL DEFAULT 1, + PRIMARY KEY (service_name, cluster_id), + FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id) +); + +-- Components table +CREATE TABLE IF NOT EXISTS servicecomponentdesiredstate ( + component_name VARCHAR(255) NOT NULL, + cluster_id BIGINT NOT NULL, + service_name VARCHAR(255) NOT NULL, + desired_state VARCHAR(255) NOT NULL DEFAULT 'INIT', + desired_stack_version VARCHAR(255) NOT NULL, + PRIMARY KEY (component_name, cluster_id, service_name), + FOREIGN KEY (cluster_id, service_name) REFERENCES clusterservices(cluster_id, service_name) +); + +-- Host components table +CREATE TABLE IF NOT EXISTS hostcomponentdesiredstate ( + cluster_id BIGINT NOT NULL, + component_name VARCHAR(255) NOT NULL, + host_id BIGINT NOT NULL, + service_name VARCHAR(255) NOT NULL, + desired_state VARCHAR(255) NOT NULL DEFAULT 'INIT', + desired_stack_version VARCHAR(255) NOT NULL, + admin_state VARCHAR(255), + maintenance_state VARCHAR(255) NOT NULL DEFAULT 'OFF', + restart_required BOOLEAN NOT NULL DEFAULT FALSE, + PRIMARY KEY (cluster_id, component_name, host_id, service_name), + FOREIGN KEY (host_id) REFERENCES hosts(host_id), + FOREIGN KEY (cluster_id, service_name) REFERENCES clusterservices(cluster_id, service_name) +); + +-- Configuration tables +CREATE TABLE IF NOT EXISTS clusterconfig ( + config_id BIGSERIAL PRIMARY KEY, + version_tag VARCHAR(255) NOT NULL, + version BIGINT NOT NULL, + type_name VARCHAR(255) NOT NULL, + cluster_id BIGINT NOT NULL, + config_data TEXT NOT NULL, + config_attributes TEXT, + create_timestamp BIGINT NOT NULL, + selected SMALLINT NOT NULL DEFAULT 0, + selected_timestamp BIGINT NOT NULL DEFAULT 0, + unmapped SMALLINT NOT NULL DEFAULT 0, + FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id), + UNIQUE (cluster_id, type_name, version_tag) +); + +-- Permissions and privileges tables +CREATE TABLE IF NOT EXISTS adminprincipal ( + principal_id BIGSERIAL PRIMARY KEY, + principal_type_id INTEGER NOT NULL DEFAULT 1 +); + +CREATE TABLE IF NOT EXISTS adminprincipaltype ( + principal_type_id SERIAL PRIMARY KEY, + principal_type_name VARCHAR(255) NOT NULL UNIQUE +); + +-- Insert default principal types +INSERT INTO adminprincipaltype (principal_type_name) VALUES ('USER') ON CONFLICT DO NOTHING; +INSERT INTO adminprincipaltype (principal_type_name) VALUES ('GROUP') ON CONFLICT DO NOTHING; +INSERT INTO adminprincipaltype (principal_type_name) VALUES ('ROLE') ON CONFLICT DO NOTHING; + +-- Create principal for admin user +INSERT INTO adminprincipal (principal_type_id) +SELECT principal_type_id FROM adminprincipaltype WHERE principal_type_name = 'USER' +ON CONFLICT DO NOTHING; + +-- Repositories table +CREATE TABLE IF NOT EXISTS repo_version ( + repo_version_id BIGSERIAL PRIMARY KEY, + stack_id BIGINT NOT NULL, + version VARCHAR(255) NOT NULL, + display_name VARCHAR(128) NOT NULL, + repo_type VARCHAR(255) NOT NULL DEFAULT 'STANDARD', + version_url VARCHAR(1024), + version_xml TEXT, + version_xsd VARCHAR(512), + parent_id BIGINT, + hidden SMALLINT NOT NULL DEFAULT 0, + resolved SMALLINT NOT NULL DEFAULT 0, + legacy SMALLINT NOT NULL DEFAULT 1, + UNIQUE (stack_id, version) +); + +-- Stacks table +CREATE TABLE IF NOT EXISTS stack ( + stack_id BIGSERIAL PRIMARY KEY, + stack_name VARCHAR(255) NOT NULL, + stack_version VARCHAR(255) NOT NULL, + UNIQUE (stack_name, stack_version) +); + +-- Insert default stack +INSERT INTO stack (stack_name, stack_version) VALUES ('HDP', '2.6') ON CONFLICT DO NOTHING; + +-- Metrics tables (simplified) +CREATE TABLE IF NOT EXISTS metricaggregate ( + metric_name VARCHAR(255) NOT NULL, + app_id VARCHAR(255) NOT NULL, + instance_id VARCHAR(255), + start_time BIGINT NOT NULL, + units VARCHAR(255), + metric_sum DOUBLE PRECISION, + metric_count INTEGER, + metric_max DOUBLE PRECISION, + metric_min DOUBLE PRECISION, + PRIMARY KEY (metric_name, app_id, instance_id, start_time) +); + +-- Views tables +CREATE TABLE IF NOT EXISTS viewmain ( + view_name VARCHAR(255) NOT NULL, + label VARCHAR(255), + description VARCHAR(2048), + version VARCHAR(255), + build VARCHAR(128), + resource_type_id INTEGER, + icon VARCHAR(255), + icon64 VARCHAR(255), + archive VARCHAR(255), + mask VARCHAR(255), + system_view SMALLINT NOT NULL DEFAULT 0, + PRIMARY KEY (view_name) +); + +-- Alerts tables (simplified) +CREATE TABLE IF NOT EXISTS alert_definition ( + definition_id BIGSERIAL PRIMARY KEY, + cluster_id BIGINT NOT NULL, + definition_name VARCHAR(255) NOT NULL, + service_name VARCHAR(255) NOT NULL, + component_name VARCHAR(255), + scope VARCHAR(255) DEFAULT 'ANY', + label VARCHAR(255), + description TEXT, + enabled SMALLINT NOT NULL DEFAULT 1, + schedule_interval INTEGER NOT NULL, + source_type VARCHAR(255) NOT NULL, + alert_source TEXT NOT NULL, + hash VARCHAR(64) NOT NULL, + ignore_host SMALLINT NOT NULL DEFAULT 0, + help_url VARCHAR(512), + repeat_tolerance INTEGER NOT NULL DEFAULT 1, + repeat_tolerance_enabled SMALLINT NOT NULL DEFAULT 0, + FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id), + UNIQUE (cluster_id, definition_name) +); + +-- Topology tables +CREATE TABLE IF NOT EXISTS topology_request ( + id BIGSERIAL PRIMARY KEY, + action VARCHAR(255) NOT NULL, + cluster_id BIGINT NOT NULL, + bp_name VARCHAR(100) NOT NULL, + cluster_properties TEXT, + cluster_attributes TEXT, + description VARCHAR(1024), + provision_action VARCHAR(255), + FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id) +); + +-- Upgrade tables +CREATE TABLE IF NOT EXISTS upgrade ( + upgrade_id BIGSERIAL PRIMARY KEY, + cluster_id BIGINT NOT NULL, + request_id BIGINT NOT NULL, + from_version VARCHAR(255) NOT NULL DEFAULT '', + to_version VARCHAR(255) NOT NULL DEFAULT '', + direction VARCHAR(255) NOT NULL DEFAULT 'UPGRADE', + upgrade_package VARCHAR(255) NOT NULL, + upgrade_type VARCHAR(32) NOT NULL, + repo_version_id BIGINT NOT NULL, + skip_failures SMALLINT NOT NULL DEFAULT 0, + skip_service_check_failures SMALLINT NOT NULL DEFAULT 0, + downgrade_allowed SMALLINT NOT NULL DEFAULT 1, + suspended SMALLINT NOT NULL DEFAULT 0, + FOREIGN KEY (cluster_id) REFERENCES clusters(cluster_id), + FOREIGN KEY (repo_version_id) REFERENCES repo_version(repo_version_id) +); + +-- Create indexes for better performance +CREATE INDEX IF NOT EXISTS idx_users_user_name ON users(user_name); +CREATE INDEX IF NOT EXISTS idx_users_user_type ON users(user_type); +CREATE INDEX IF NOT EXISTS idx_clusters_cluster_name ON clusters(cluster_name); +CREATE INDEX IF NOT EXISTS idx_hosts_host_name ON hosts(host_name); +CREATE INDEX IF NOT EXISTS idx_clusterservices_cluster_id ON clusterservices(cluster_id); +CREATE INDEX IF NOT EXISTS idx_clusterconfig_cluster_id ON clusterconfig(cluster_id); +CREATE INDEX IF NOT EXISTS idx_clusterconfig_type_name ON clusterconfig(type_name); + +-- Grant permissions +GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ambari; +GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ambari; +GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO ambari; + +-- Create a function to update modified timestamps +CREATE OR REPLACE FUNCTION update_modified_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.modified_date = CURRENT_TIMESTAMP; + RETURN NEW; +END; +$$ language 'plpgsql'; + +-- Create triggers for timestamp updates +DROP TRIGGER IF EXISTS update_users_modtime ON users; +CREATE TRIGGER update_users_modtime + BEFORE UPDATE ON users + FOR EACH ROW EXECUTE FUNCTION update_modified_column(); + +-- Insert some sample data for development +DO $$ +BEGIN + -- Insert sample cluster if not exists + IF NOT EXISTS (SELECT 1 FROM clusters WHERE cluster_name = 'development') THEN + INSERT INTO clusters (cluster_name, cluster_info, desired_stack_version) + VALUES ('development', 'Development Cluster', '{"stackName":"HDP","stackVersion":"2.6"}'); + END IF; + + -- Insert localhost as a host if not exists + IF NOT EXISTS (SELECT 1 FROM hosts WHERE host_name = 'localhost') THEN + INSERT INTO hosts (host_name, cpu_count, cpu_info, os_arch, os_type, total_mem, rack_info) + VALUES ('localhost', 4, 'Intel Core i7', 'x86_64', 'centos7', 8589934592, '/default-rack'); + END IF; +END $$; + +-- Create a view for easy cluster monitoring +CREATE OR REPLACE VIEW cluster_summary AS +SELECT + c.cluster_id, + c.cluster_name, + c.cluster_state, + c.desired_cluster_state, + c.security_type, + COUNT(DISTINCT h.host_id) as host_count, + COUNT(DISTINCT cs.service_name) as service_count +FROM clusters c +LEFT JOIN hosts h ON TRUE -- All hosts for now, should join through cluster_host_mapping +LEFT JOIN clusterservices cs ON c.cluster_id = cs.cluster_id +GROUP BY c.cluster_id, c.cluster_name, c.cluster_state, c.desired_cluster_state, c.security_type; + +-- Create a function to get cluster health +CREATE OR REPLACE FUNCTION get_cluster_health(cluster_name_param VARCHAR) +RETURNS TABLE ( + cluster_name VARCHAR, + total_hosts BIGINT, + total_services BIGINT, + cluster_state VARCHAR, + last_updated TIMESTAMP +) AS $$ +BEGIN + RETURN QUERY + SELECT + c.cluster_name, + COUNT(DISTINCT h.host_id) as total_hosts, + COUNT(DISTINCT cs.service_name) as total_services, + c.cluster_state, + CURRENT_TIMESTAMP as last_updated + FROM clusters c + LEFT JOIN hosts h ON TRUE + LEFT JOIN clusterservices cs ON c.cluster_id = cs.cluster_id + WHERE c.cluster_name = cluster_name_param + GROUP BY c.cluster_name, c.cluster_state; +END; +$$ LANGUAGE plpgsql; + +-- Set up database maintenance +-- Create a function to clean old metrics data +CREATE OR REPLACE FUNCTION cleanup_old_metrics(days_to_keep INTEGER DEFAULT 30) +RETURNS INTEGER AS $$ +DECLARE + deleted_count INTEGER; + cutoff_time BIGINT; +BEGIN + -- Calculate cutoff time (current time - days_to_keep in milliseconds) + cutoff_time := EXTRACT(EPOCH FROM CURRENT_TIMESTAMP - INTERVAL '1 day' * days_to_keep) * 1000; + + -- Delete old metrics + DELETE FROM metricaggregate WHERE start_time < cutoff_time; + GET DIAGNOSTICS deleted_count = ROW_COUNT; + + RETURN deleted_count; +END; +$$ LANGUAGE plpgsql; + +-- Create database statistics view +CREATE OR REPLACE VIEW database_stats AS +SELECT + schemaname, + tablename, + attname as column_name, + n_distinct, + correlation +FROM pg_stats +WHERE schemaname = 'public' +ORDER BY schemaname, tablename, attname; + +\echo 'Ambari database initialization completed successfully!' +\echo 'Default admin user created: admin/admin' +\echo 'Sample development cluster created' +\echo 'Database is ready for Ambari Server setup'