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
|
||||||
6
site.yml
6
site.yml
@@ -11,8 +11,10 @@
|
|||||||
# Infrastructure services
|
# Infrastructure services
|
||||||
# - role: postgresql
|
# - role: postgresql
|
||||||
# tags: ['postgresql', 'infrastructure', 'database']
|
# tags: ['postgresql', 'infrastructure', 'database']
|
||||||
- role: valkey
|
# - role: valkey
|
||||||
tags: ['valkey', 'redis', 'infrastructure', 'cache']
|
# tags: ['valkey', 'redis', 'infrastructure', 'cache']
|
||||||
|
- role: podman
|
||||||
|
tags: ['podman', 'containers', 'infrastructure']
|
||||||
# - role: caddy
|
# - role: caddy
|
||||||
# tags: ['caddy', 'infrastructure', 'web']
|
# tags: ['caddy', 'infrastructure', 'web']
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user