Add Podman container infrastructure role for containerized services

- Implemented complete Podman infrastructure role following rick-infra patterns
- Minimal installation approach: only install podman, trust Arch dependency management
- Configured with crun runtime for optimal performance and security
- Security-focused: HTTPS-only registries, rootless containers, systemd hardening
- Registry support: docker.io, quay.io, ghcr.io with secure configurations
- Ready for service-specific users with isolated container environments
- Quadlet support for native systemd container management
- Container-to-host networking via bridge networks with host gateway access
- Foundation for future containerized services (Authentik, Nextcloud)
- Maintains rick-infra philosophy: infrastructure provides foundation, apps manage specifics
This commit is contained in:
2025-11-20 22:11:44 +01:00
parent 3b062edeb6
commit 500224b5de
8 changed files with 483 additions and 2 deletions

185
roles/podman/README.md Normal file
View File

@@ -0,0 +1,185 @@
# Podman Infrastructure Role
This role provides Podman container infrastructure for the rick-infra project, following the same patterns established by the PostgreSQL and Valkey infrastructure roles.
## Overview
**Podman** is a daemonless container engine for developing, managing, and running OCI containers and pods on Linux systems. This role establishes the foundational container infrastructure that containerized application services can build upon.
Podman is deployed as a system-level infrastructure service that provides container runtime capabilities for service-specific users to utilize.
## Features
- **Daemonless architecture**: No background daemon required, improved security
- **Rootless containers**: Applications run containers as dedicated users
- **OCI compliance**: Full Docker compatibility with enhanced security
- **Systemd integration**: Native systemd integration via quadlet files
- **Security-focused**: crun runtime, secure registries, restrictive defaults
- **Infrastructure pattern**: Matches PostgreSQL/Valkey role architecture
## Architecture
### **Container Runtime Stack:**
- **Podman**: Container engine and CLI
- **crun**: Fast, lightweight OCI runtime (instead of runc)
- **netavark**: Modern container networking
- **aardvark-dns**: Container DNS resolution
- **conmon**: Container monitoring
- **catatonit**: Container init process
### **Registry Configuration:**
- **docker.io**: Docker Hub (primary)
- **quay.io**: Red Hat Quay
- **ghcr.io**: GitHub Container Registry
All registries configured with HTTPS-only, no insecure connections allowed.
## Application Integration
Applications should create service-specific users and manage their own container deployments:
### **Service-Specific User Pattern:**
```yaml
# Example from future authentik role
- name: Create authentik user
user:
name: authentik
system: yes
shell: /bin/bash
home: /var/lib/authentik
create_home: yes
- name: Configure rootless podman for authentik
lineinfile:
path: "{{ item.file }}"
line: "authentik:{{ item.start }}:{{ item.count }}"
loop:
- { file: /etc/subuid, start: 100000, count: 65536 }
- { file: /etc/subgid, start: 100000, count: 65536 }
```
### **Quadlet Integration:**
```yaml
# Deploy quadlet files to user systemd directory
- name: Deploy container quadlets
template:
src: "{{ item }}.j2"
dest: "/var/lib/authentik/.config/containers/systemd/{{ item }}"
owner: authentik
group: authentik
loop:
- authentik.pod
- authentik-server.container
- authentik-worker.container
```
### **Container-to-Host Connectivity:**
```ini
# Pod quadlet with host access
[Pod]
Network=service-internal
AddHost=host.containers.internal:host-gateway
PublishPort=127.0.0.1:9000:9000/tcp
```
```bash
# Environment variables for host service access
DATABASE_HOST=host.containers.internal
REDIS_HOST=host.containers.internal
```
## Configuration
### **Default Settings:**
```yaml
# Service management
podman_service_enabled: true
podman_service_state: "started"
# Registry configuration
podman_registries:
- docker.io
- quay.io
- ghcr.io
# Security settings
podman_rootless: true
podman_systemd_security: true
```
All settings use secure defaults and can be overridden in host_vars if needed.
## Dependencies
This is an infrastructure role with no dependencies. Applications that need containers should declare this role as a dependency:
```yaml
# roles/authentik/meta/main.yml
dependencies:
- role: postgresql
- role: valkey
- role: podman # Container infrastructure
- role: caddy
```
## Service Management
```bash
# System service (API endpoint)
sudo systemctl status podman
sudo systemctl status podman.socket
# Container functionality
sudo podman --version
sudo podman run --rm hello-world
# User containers (example with authentik user)
sudo -u authentik systemctl --user status authentik-pod
sudo -u authentik podman ps -a
```
## Container User Isolation
Each containerized service gets:
- **Dedicated system user** (e.g., `authentik`, `nextcloud`)
- **Isolated subuid/subgid ranges** (100000+65536 IDs per service)
- **Private container storage** in user home directory
- **User systemd session** for container service management
- **Network isolation** via custom bridge networks
## File Locations
- **Global configuration**: `/etc/containers/`
- `registries.conf` - Registry settings
- `containers.conf` - Global podman settings
- **User containers**: `/var/lib/{service}/`
- `.config/containers/systemd/` - Quadlet files
- `.config/systemd/user/` - Generated systemd services
- `.local/share/containers/` - Container storage
## Security
- **Rootless operation**: All containers run as unprivileged users
- **Registry security**: HTTPS-only, trusted registries
- **Runtime security**: crun with security features enabled
- **Network isolation**: Custom networks, no privileged networking
- **Storage isolation**: Per-user container storage
- **Systemd integration**: Full systemd security features available
## Integration with Host Services
Containerized applications access host services (PostgreSQL, Valkey) via:
- **Bridge networking** with host gateway access
- **Host mapping**: `host.containers.internal` → host IP
- **Localhost binding**: Host services remain on 127.0.0.1
- **Standard ports**: No port conflicts, containers use bridge networks
## Notes
This role follows the rick-infra infrastructure pattern where foundational services (Podman, PostgreSQL, Valkey) are provided as host-level infrastructure, and applications manage their own specific usage patterns and user isolation rather than sharing a common container user.
**Architecture Benefits:**
- Clear separation between infrastructure and applications
- Service-level isolation and security
- Native systemd integration for all containers
- Familiar management patterns consistent with native services

View File

@@ -0,0 +1,73 @@
---
# =================================================================
# Podman Infrastructure Role - Simplified Configuration
# =================================================================
# Provides rootless container infrastructure for applications
# Applications manage their own service-specific users and deployments
# =================================================================
# Essential Configuration
# =================================================================
# Service Management
podman_service_enabled: true
podman_service_state: "started"
# Installation Configuration (Arch Linux optimized)
podman_install_optional: false # Trust pacman dependency management
# =================================================================
# Container Runtime Security
# =================================================================
# Rootless container configuration
podman_rootless: true
podman_systemd_security: true
# =================================================================
# Registry Configuration
# =================================================================
# Default container registries (secure, trusted sources)
podman_registries:
- docker.io
- quay.io
- ghcr.io
# Registry security settings
podman_registry_insecure: false
podman_registry_blocked: false
# =================================================================
# Network Configuration
# =================================================================
# Default networking (applications create their own networks)
podman_default_network: "bridge"
podman_network_security: true
# =================================================================
# Storage Configuration
# =================================================================
# Container storage settings
podman_storage_driver: "overlay"
podman_storage_security: true
# =================================================================
# Infrastructure Notes
# =================================================================
# This role provides minimal podman infrastructure
# Applications should manage their own configurations:
#
# Service-specific users:
# - Applications create users like: authentik, nextcloud, etc.
# - Each user gets isolated subuid/subgid ranges
# - Each user manages their own containers via systemd --user
#
# Container networking:
# - Applications create bridge networks for isolation
# - Host services accessed via host.containers.internal
# - Port publishing only to localhost for security
#
# Podman's built-in defaults are used for everything else

View File

@@ -0,0 +1,13 @@
---
# Podman Infrastructure Role - Handlers
# Matches the handler pattern from other infrastructure roles
- name: reload systemd
systemd:
daemon_reload: yes
- name: restart podman
systemd:
name: podman
state: restarted
when: podman_service_enabled | default(true)

View File

@@ -0,0 +1,27 @@
---
# Podman Infrastructure Role - Meta Information
galaxy_info:
author: rick-infra
description: Podman container infrastructure role for rick-infra project
company: Personal Infrastructure
license: MIT
min_ansible_version: 2.9
platforms:
- name: ArchLinux
versions:
- all
galaxy_tags:
- podman
- containers
- infrastructure
- systemd
- rootless
# Dependencies
# Podman is a foundational infrastructure service with no dependencies
dependencies: []
# Role provides container infrastructure for other services to consume

View File

@@ -0,0 +1,79 @@
---
# Podman Infrastructure Role - Simplified Tasks
- name: Update package cache
pacman:
update_cache: yes
- name: Install crun as OCI runtime (faster than runc)
pacman:
name: crun
state: present
- name: Install Podman container runtime
pacman:
name: podman
state: present
- name: Verify podman installation
command: podman --version
register: podman_version_check
changed_when: false
- name: Create global containers configuration directory
file:
path: /etc/containers
state: directory
mode: '0755'
- name: Configure global container registries
template:
src: registries.conf.j2
dest: /etc/containers/registries.conf
mode: '0644'
backup: yes
notify: restart podman
- name: Configure global podman settings
template:
src: containers.conf.j2
dest: /etc/containers/containers.conf
mode: '0644'
backup: yes
notify: restart podman
- name: Enable podman system service (if enabled)
systemd:
name: podman
enabled: "{{ podman_service_enabled }}"
state: "{{ podman_service_state }}"
daemon_reload: yes
when: podman_service_enabled
- name: Test podman functionality
command: podman info --format json
register: podman_info_result
changed_when: false
- name: Verify rootless podman configuration
command: podman system info
register: podman_system_info
changed_when: false
failed_when: false
- name: Display Podman infrastructure status
debug:
msg: |
✅ Podman container infrastructure ready!
🐳 Version: {{ podman_version_check.stdout.split()[2] | default('unknown') }}
🔒 Security: Rootless container runtime enabled
📦 Registries: {{ podman_registries | join(', ') }}
🏗️ Storage: {{ 'overlay' if 'overlay' in podman_system_info.stdout else 'system default' }}
🚀 Ready for containerized applications!
📋 Next Steps:
- Applications should create service-specific users
- Each user gets isolated container environment
- Services deploy quadlet files for systemd integration

View File

@@ -0,0 +1,67 @@
# Podman Configuration - Generated by Ansible
# rick-infra Podman Infrastructure Role
#
# Global podman configuration providing secure defaults
# for containerized applications
# =================================================================
# Container Engine Configuration
# =================================================================
[engine]
# Container runtime (OCI compliant)
# runtime = "runc" # Default, can be overridden to crun
# Network backend for container networking
network_backend = "netavark"
# Default network for new containers
default_network = "{{ podman_default_network }}"
# =================================================================
# Storage Configuration
# =================================================================
# Storage driver for container layers and images
# driver = "{{ podman_storage_driver }}" # overlay is default
# =================================================================
# Security Configuration
# =================================================================
# Enable security features
# seccomp_profile = "/usr/share/containers/seccomp.json"
# apparmor_profile = "containers-default-0.14.5"
# =================================================================
# Network Configuration
# =================================================================
[network]
# Default subnet for new networks (applications override this)
default_subnet = "10.88.0.0/16"
default_subnet_pools = [
{"base" = "10.89.0.0/16", "size" = 24},
{"base" = "10.90.0.0/16", "size" = 24}
]
# =================================================================
# Service Integration
# =================================================================
[service_destinations]
# Systemd integration for container services
# Applications use this for quadlet deployment
# =================================================================
# Infrastructure Notes
# =================================================================
# This configuration provides secure defaults for all containers
# Applications should:
# - Create service-specific users for container isolation
# - Use quadlet files for systemd integration
# - Create custom networks for multi-container applications
# - Access host services via host.containers.internal

View File

@@ -0,0 +1,35 @@
# Container Registry Configuration - Generated by Ansible
# rick-infra Podman Infrastructure Role
#
# This configuration defines trusted container registries
# for secure container image retrieval
# =================================================================
# Registry Search Configuration
# =================================================================
# Default registries to search when pulling unqualified image names
# Images without a registry prefix will search these in order
unqualified-search-registries = {{ podman_registries | to_json }}
{% for registry in podman_registries %}
# =================================================================
# {{ registry | title }} Registry Configuration
# =================================================================
[[registry]]
location = "{{ registry }}"
insecure = {{ podman_registry_insecure | lower }}
blocked = {{ podman_registry_blocked | lower }}
{% endfor %}
# =================================================================
# Security Notes
# =================================================================
# All registries configured with:
# - insecure: false (HTTPS required)
# - blocked: false (registry accessible)
#
# Additional registries can be added by applications as needed
# following the same security-first configuration pattern

View File

@@ -11,8 +11,10 @@
# Infrastructure services
# - role: postgresql
# tags: ['postgresql', 'infrastructure', 'database']
- role: valkey
tags: ['valkey', 'redis', 'infrastructure', 'cache']
# - role: valkey
# tags: ['valkey', 'redis', 'infrastructure', 'cache']
- role: podman
tags: ['podman', 'containers', 'infrastructure']
# - role: caddy
# tags: ['caddy', 'infrastructure', 'web']