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:
185
roles/podman/README.md
Normal file
185
roles/podman/README.md
Normal 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
|
||||
73
roles/podman/defaults/main.yml
Normal file
73
roles/podman/defaults/main.yml
Normal 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
|
||||
13
roles/podman/handlers/main.yml
Normal file
13
roles/podman/handlers/main.yml
Normal 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)
|
||||
27
roles/podman/meta/main.yml
Normal file
27
roles/podman/meta/main.yml
Normal 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
|
||||
79
roles/podman/tasks/main.yml
Normal file
79
roles/podman/tasks/main.yml
Normal 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
|
||||
67
roles/podman/templates/containers.conf.j2
Normal file
67
roles/podman/templates/containers.conf.j2
Normal 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
|
||||
35
roles/podman/templates/registries.conf.j2
Normal file
35
roles/podman/templates/registries.conf.j2
Normal 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
|
||||
Reference in New Issue
Block a user