395 lines
8.6 KiB
Markdown
395 lines
8.6 KiB
Markdown
# Podman Role
|
|
|
|
**Bootstrap containerized applications with Podman in minutes.**
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### 1. Basic Setup
|
|
```yaml
|
|
- hosts: servers
|
|
roles:
|
|
- podman
|
|
```
|
|
|
|
### 2. Run Your First Container
|
|
```yaml
|
|
- hosts: servers
|
|
roles:
|
|
- role: podman
|
|
vars:
|
|
podman_containers:
|
|
- name: nginx
|
|
image: nginx:latest
|
|
state: started
|
|
ports:
|
|
- "80:80"
|
|
```
|
|
|
|
### 3. Common Patterns
|
|
|
|
**Web application with database:**
|
|
```yaml
|
|
podman_containers:
|
|
- name: webapp
|
|
image: myapp:latest
|
|
state: started
|
|
ports:
|
|
- "8080:8080"
|
|
env:
|
|
DATABASE_URL: "postgresql://postgres@db:5432/app"
|
|
|
|
- name: database
|
|
image: postgres:15
|
|
state: started
|
|
volumes:
|
|
- "db-data:/var/lib/postgresql/data"
|
|
env:
|
|
POSTGRES_DB: app
|
|
POSTGRES_PASSWORD: secret
|
|
|
|
podman_volumes:
|
|
- name: db-data
|
|
```
|
|
|
|
**That's it!** Podman will be installed, configured, and your containers will be running with systemd services automatically created.
|
|
|
|
---
|
|
|
|
## 📋 Requirements
|
|
|
|
- **Ansible**: 2.11+
|
|
- **Target OS**: Ubuntu 20.04+, Debian 11+
|
|
- **Collection**: `containers.podman` (auto-installed)
|
|
|
|
---
|
|
|
|
## 🔧 Complete Feature Reference
|
|
|
|
### Container Management
|
|
|
|
```yaml
|
|
podman_containers:
|
|
- name: my-app
|
|
image: nginx:latest
|
|
state: started # started|stopped|present|absent
|
|
ports:
|
|
- "8080:80"
|
|
- "443:443"
|
|
volumes:
|
|
- "/host/path:/container/path"
|
|
- "volume-name:/data"
|
|
env:
|
|
ENV_VAR: value
|
|
networks:
|
|
- app-network
|
|
restart_policy: always # no|always|on-failure|unless-stopped
|
|
user: "1000:1000"
|
|
labels:
|
|
app: web
|
|
environment: prod
|
|
memory: "1g"
|
|
cpu_shares: 1024
|
|
device:
|
|
- "/dev/sda:/dev/xvda:rwm"
|
|
security_opt:
|
|
- "seccomp=unconfined"
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
# Systemd service generation (optional)
|
|
generate_systemd:
|
|
path: "/etc/systemd/system"
|
|
restart_policy: always
|
|
after: ["network.target"]
|
|
wants: ["network-online.target"]
|
|
```
|
|
|
|
### Network Management
|
|
|
|
```yaml
|
|
podman_networks:
|
|
- name: app-network
|
|
state: present
|
|
driver: bridge # bridge|macvlan|ipvlan
|
|
subnet: "172.20.0.0/16"
|
|
gateway: "172.20.0.1"
|
|
internal: false # true for isolated networks
|
|
dns:
|
|
- "8.8.8.8"
|
|
- "1.1.1.1"
|
|
options:
|
|
mtu: 1500
|
|
vlan: 100
|
|
|
|
# Advanced networking
|
|
- name: macvlan-net
|
|
driver: macvlan
|
|
macvlan: "eth0" # Parent interface
|
|
subnet: "192.168.1.0/24"
|
|
|
|
- name: ipv6-net
|
|
driver: bridge
|
|
subnet: "fd00::/64"
|
|
ipv6: true
|
|
```
|
|
|
|
### Volume Management
|
|
|
|
```yaml
|
|
podman_volumes:
|
|
- name: app-data
|
|
state: present
|
|
driver: local # local|tmpfs
|
|
labels:
|
|
backup: daily
|
|
environment: prod
|
|
options:
|
|
- "device=/dev/sdb1"
|
|
- "type=ext4"
|
|
- "o=rw"
|
|
|
|
- name: tmpfs-volume
|
|
driver: tmpfs
|
|
options:
|
|
- "tmpfs-size=100m"
|
|
- "tmpfs-mode=1777"
|
|
```
|
|
|
|
### Pod Management
|
|
|
|
```yaml
|
|
podman_pods:
|
|
- name: webapp-pod
|
|
state: started
|
|
ports:
|
|
- "8080:80"
|
|
networks:
|
|
- frontend
|
|
hostname: webapp
|
|
dns:
|
|
- "8.8.8.8"
|
|
labels:
|
|
app: webapp
|
|
volumes:
|
|
- "webapp-data:/data"
|
|
memory: "2g"
|
|
cpu_shares: 1024
|
|
share: "net,ipc" # Shared namespaces
|
|
infra: true # Use infra container
|
|
infra_image: "registry.k8s.io/pause:3.9"
|
|
```
|
|
|
|
### Advanced Configuration
|
|
|
|
#### Registry & Security Policy
|
|
```yaml
|
|
# Basic registry setup (development)
|
|
podman_policy_default_type: "insecureAcceptAnything"
|
|
podman_policy_reject_unknown_registries: false
|
|
|
|
# Production security (with signatures)
|
|
podman_policy_default_type: "reject"
|
|
podman_policy_reject_unknown_registries: true
|
|
podman_policy_trusted_registries:
|
|
- registry: "docker.io"
|
|
type: "insecureAcceptAnything"
|
|
unqualified_search: true
|
|
|
|
- registry: "internal.company.com"
|
|
type: "signedBy"
|
|
keyPath: "/etc/pki/containers/company.gpg"
|
|
insecure: false
|
|
mirror:
|
|
- location: "backup.company.com"
|
|
```
|
|
|
|
#### Systemd Service Generation
|
|
```yaml
|
|
# Global systemd settings
|
|
podman_generate_systemd: true
|
|
podman_systemd_options:
|
|
restart_policy: always
|
|
stop_timeout: 120
|
|
after: ["network.target"]
|
|
wants: ["network-online.target"]
|
|
container_prefix: "container-"
|
|
pod_prefix: "pod-"
|
|
```
|
|
|
|
#### Resource Cleanup
|
|
```yaml
|
|
# Auto-cleanup unused resources
|
|
podman_prune_enabled: true
|
|
podman_prune_options:
|
|
container: true # Remove stopped containers
|
|
image: true # Remove unused images
|
|
network: true # Remove unused networks
|
|
volume: true # Remove unused volumes
|
|
system: true # Full system cleanup
|
|
```
|
|
|
|
#### Storage Configuration
|
|
```yaml
|
|
podman_configure_storage: true
|
|
podman_storage_driver: overlay
|
|
podman_storage_graphroot: /var/lib/containers/storage
|
|
podman_storage_runroot: /run/containers/storage
|
|
```
|
|
|
|
#### API & Socket Services
|
|
```yaml
|
|
podman_enable_socket: true # Enable Podman socket
|
|
podman_enable_api_service: true # Enable REST API
|
|
```
|
|
|
|
---
|
|
|
|
## 🏷️ Available Tags
|
|
|
|
Run specific parts of the role:
|
|
|
|
```bash
|
|
# Install only
|
|
ansible-playbook -t podman-install playbook.yml
|
|
|
|
# Configure only
|
|
ansible-playbook -t podman-configure playbook.yml
|
|
|
|
# Manage containers only
|
|
ansible-playbook -t podman-containers playbook.yml
|
|
|
|
# Manage networks only
|
|
ansible-playbook -t podman-networks playbook.yml
|
|
```
|
|
|
|
**Available tags:**
|
|
- `podman` - Run everything
|
|
- `podman-install` - Package installation
|
|
- `podman-configure` - Configuration files
|
|
- `podman-services` - System services
|
|
- `podman-networks` - Network management
|
|
- `podman-volumes` - Volume management
|
|
- `podman-pods` - Pod management
|
|
- `podman-containers` - Container management
|
|
- `podman-systemd` - Systemd service generation
|
|
- `podman-prune` - Resource cleanup
|
|
|
|
---
|
|
|
|
## 📚 Example Playbooks
|
|
|
|
### Development Environment
|
|
```yaml
|
|
- hosts: dev-servers
|
|
roles:
|
|
- role: podman
|
|
vars:
|
|
# Permissive for development
|
|
podman_policy_default_type: "insecureAcceptAnything"
|
|
podman_enable_socket: true
|
|
|
|
podman_containers:
|
|
- name: dev-web
|
|
image: nginx:latest
|
|
state: started
|
|
ports:
|
|
- "8080:80"
|
|
volumes:
|
|
- "./web:/usr/share/nginx/html"
|
|
```
|
|
|
|
### Production Environment
|
|
```yaml
|
|
- hosts: prod-servers
|
|
roles:
|
|
- role: podman
|
|
vars:
|
|
# Strict security for production
|
|
podman_policy_default_type: "reject"
|
|
podman_policy_reject_unknown_registries: true
|
|
podman_policy_trusted_registries:
|
|
- registry: "registry.company.com"
|
|
type: "signedBy"
|
|
keyPath: "/etc/pki/containers/prod.gpg"
|
|
|
|
podman_containers:
|
|
- name: prod-app
|
|
image: registry.company.com/app:v1.2.3
|
|
state: started
|
|
restart_policy: always
|
|
memory: "2g"
|
|
cpu_shares: 2048
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
```
|
|
|
|
### Multi-Service Application
|
|
```yaml
|
|
- hosts: app-servers
|
|
roles:
|
|
- role: podman
|
|
vars:
|
|
podman_networks:
|
|
- name: app-network
|
|
subnet: "172.20.0.0/16"
|
|
|
|
podman_volumes:
|
|
- name: postgres-data
|
|
- name: redis-data
|
|
- name: app-uploads
|
|
|
|
podman_containers:
|
|
# Database
|
|
- name: postgres
|
|
image: postgres:15
|
|
state: started
|
|
networks:
|
|
- app-network
|
|
volumes:
|
|
- "postgres-data:/var/lib/postgresql/data"
|
|
env:
|
|
POSTGRES_DB: myapp
|
|
POSTGRES_PASSWORD: "{{ vault_db_password }}"
|
|
|
|
# Cache
|
|
- name: redis
|
|
image: redis:7-alpine
|
|
state: started
|
|
networks:
|
|
- app-network
|
|
volumes:
|
|
- "redis-data:/data"
|
|
|
|
# Application
|
|
- name: app
|
|
image: myapp:latest
|
|
state: started
|
|
networks:
|
|
- app-network
|
|
ports:
|
|
- "80:8080"
|
|
volumes:
|
|
- "app-uploads:/app/uploads"
|
|
env:
|
|
DATABASE_URL: "postgresql://postgres:{{ vault_db_password }}@postgres:5432/myapp"
|
|
REDIS_URL: "redis://redis:6379"
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
```
|
|
|
|
---
|
|
|
|
## 📄 License
|
|
|
|
MIT
|
|
|
|
## 👤 Author
|
|
|
|
Daniel Akulenok <podman@valid.dk>
|