cleanup
This commit is contained in:
parent
f7f825a251
commit
b1999d4831
81 changed files with 633 additions and 5108 deletions
|
|
@ -33,12 +33,12 @@
|
||||||
- rsync
|
- rsync
|
||||||
- tmux
|
- tmux
|
||||||
- nano
|
- nano
|
||||||
- the_silver_searcher
|
- the-silver-searcher
|
||||||
- net-tools
|
- net-tools
|
||||||
- mlocate
|
- plocate
|
||||||
- fail2ban
|
- fail2ban
|
||||||
- munin-node
|
- munin-node
|
||||||
- nethogs
|
# - nethogs # Not available in AlmaLinux EPEL
|
||||||
- pv
|
- pv
|
||||||
- selinux-policy
|
- selinux-policy
|
||||||
- tar
|
- tar
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: ghost-content
|
|
||||||
namespace: blog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
storageClassName: local-path
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: ghost
|
|
||||||
namespace: blog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: ghost
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: ghost
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: ghost
|
|
||||||
image: ghost:6
|
|
||||||
ports:
|
|
||||||
- containerPort: 2368
|
|
||||||
name: http
|
|
||||||
env:
|
|
||||||
- name: NODE_ENV
|
|
||||||
value: production
|
|
||||||
- name: url
|
|
||||||
value: https://w5isp.com
|
|
||||||
- name: database__client
|
|
||||||
value: mysql
|
|
||||||
- name: database__connection__host
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: database__connection__port
|
|
||||||
value: "3306"
|
|
||||||
- name: database__connection__database
|
|
||||||
value: ghost
|
|
||||||
- name: database__connection__user
|
|
||||||
value: ghost
|
|
||||||
- name: database__connection__password
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: ghost-db-secret
|
|
||||||
key: password
|
|
||||||
- name: mail__transport
|
|
||||||
value: SMTP
|
|
||||||
- name: mail__from
|
|
||||||
value: noreply@w5isp.com
|
|
||||||
- name: mail__options__service
|
|
||||||
value: Sendgrid
|
|
||||||
- name: mail__options__auth__user
|
|
||||||
value: apikey
|
|
||||||
- name: mail__options__auth__pass
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: ghost-smtp
|
|
||||||
key: password
|
|
||||||
optional: true
|
|
||||||
volumeMounts:
|
|
||||||
- name: ghost-content
|
|
||||||
mountPath: /var/lib/ghost/content
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: ghost-content
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: ghost-content
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: ghost
|
|
||||||
namespace: blog
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: ghost
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 2368
|
|
||||||
protocol: TCP
|
|
||||||
type: LoadBalancer
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: ghost-tailscale
|
|
||||||
namespace: blog
|
|
||||||
annotations:
|
|
||||||
tailscale.com/expose: "true"
|
|
||||||
tailscale.com/hostname: "ghost"
|
|
||||||
tailscale.com/tags: "tag:k8s"
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: ghost
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 2368
|
|
||||||
protocol: TCP
|
|
||||||
type: ClusterIP
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: wavelog-data
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 10Gi
|
|
||||||
storageClassName: local-path
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: wavelog-uploads
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 20Gi
|
|
||||||
storageClassName: local-path
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: ghcr.io/wavelog/wavelog:latest
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
env:
|
|
||||||
- name: WAVELOG_DB_TYPE
|
|
||||||
value: mysql
|
|
||||||
- name: WAVELOG_DB_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: WAVELOG_DB_PORT
|
|
||||||
value: "3306"
|
|
||||||
- name: WAVELOG_DB_NAME
|
|
||||||
value: wavelog
|
|
||||||
- name: WAVELOG_DB_USER
|
|
||||||
value: wavelog
|
|
||||||
- name: WAVELOG_DB_PASS
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
- name: WAVELOG_BASE_URL
|
|
||||||
value: https://log.w5isp.com
|
|
||||||
volumeMounts:
|
|
||||||
- name: wavelog-data
|
|
||||||
mountPath: /var/www/wavelog
|
|
||||||
- name: wavelog-uploads
|
|
||||||
mountPath: /var/www/wavelog/uploads
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: wavelog-data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-data
|
|
||||||
- name: wavelog-uploads
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-uploads
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: wavelog
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 80
|
|
||||||
protocol: TCP
|
|
||||||
type: LoadBalancer
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: wavelog-tailscale
|
|
||||||
namespace: wavelog
|
|
||||||
annotations:
|
|
||||||
tailscale.com/expose: "true"
|
|
||||||
tailscale.com/hostname: "wavelog"
|
|
||||||
tailscale.com/tags: "tag:k8s"
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: wavelog
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
targetPort: 80
|
|
||||||
protocol: TCP
|
|
||||||
type: ClusterIP
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
[defaults]
|
|
||||||
inventory = inventory.yml
|
|
||||||
host_key_checking = False
|
|
||||||
retry_files_enabled = False
|
|
||||||
|
|
||||||
[ssh_connection]
|
|
||||||
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
---
|
|
||||||
- name: Bootstrap AlmaLinux server for Ansible management
|
|
||||||
hosts: caddy
|
|
||||||
become: yes
|
|
||||||
vars:
|
|
||||||
ansible_user: graham # Connect as graham initially
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create ansible user
|
|
||||||
user:
|
|
||||||
name: ansible
|
|
||||||
uid: 10001
|
|
||||||
shell: /bin/bash
|
|
||||||
home: /home/ansible
|
|
||||||
create_home: yes
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Add ansible user to wheel group
|
|
||||||
user:
|
|
||||||
name: ansible
|
|
||||||
groups: wheel
|
|
||||||
append: yes
|
|
||||||
|
|
||||||
- name: Ensure .ssh directory exists for ansible user
|
|
||||||
file:
|
|
||||||
path: /home/ansible/.ssh
|
|
||||||
state: directory
|
|
||||||
owner: ansible
|
|
||||||
group: ansible
|
|
||||||
mode: "0700"
|
|
||||||
|
|
||||||
- name: Add ansible SSH key to ansible user
|
|
||||||
authorized_key:
|
|
||||||
user: ansible
|
|
||||||
key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb graham@mbp14.local"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Add SSH keys from GitHub to graham user
|
|
||||||
authorized_key:
|
|
||||||
user: graham
|
|
||||||
key: "https://github.com/gmcintire.keys"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Configure passwordless sudo for ansible user
|
|
||||||
copy:
|
|
||||||
content: "ansible ALL=(ALL) NOPASSWD: ALL"
|
|
||||||
dest: /etc/sudoers.d/ansible
|
|
||||||
mode: "0440"
|
|
||||||
validate: "visudo -cf %s"
|
|
||||||
|
|
||||||
- name: Install Python 3 (required for Ansible)
|
|
||||||
dnf:
|
|
||||||
name:
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Set Python 3 as default python
|
|
||||||
alternatives:
|
|
||||||
name: python
|
|
||||||
link: /usr/bin/python
|
|
||||||
path: /usr/bin/python3
|
|
||||||
|
|
||||||
- name: Verify ansible user can sudo
|
|
||||||
command: sudo -u ansible sudo -l
|
|
||||||
changed_when: false
|
|
||||||
register: sudo_test
|
|
||||||
|
|
||||||
- name: Show sudo verification
|
|
||||||
debug:
|
|
||||||
msg: "Ansible user sudo access verified"
|
|
||||||
when: sudo_test.rc == 0
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
||||||
---
|
|
||||||
- name: Configure Caddy reverse proxy with Tailscale on AlmaLinux 10
|
|
||||||
hosts: caddy
|
|
||||||
become: yes
|
|
||||||
gather_facts: yes
|
|
||||||
strategy: free
|
|
||||||
vars:
|
|
||||||
tailscale_key: "{{ lookup('env', 'TAILSCALE_KEY') }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Enable passwordless sudo on AlmaLinux
|
|
||||||
ansible.builtin.lineinfile:
|
|
||||||
path: /etc/sudoers
|
|
||||||
state: present
|
|
||||||
regexp: "^%wheel"
|
|
||||||
line: "%wheel ALL=(ALL) NOPASSWD: ALL"
|
|
||||||
validate: "visudo -cf %s"
|
|
||||||
|
|
||||||
- name: Clean up repository files
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
state: absent
|
|
||||||
loop:
|
|
||||||
- /etc/yum.repos.d/caddy.repo
|
|
||||||
- /etc/yum.repos.d/tailscale-stable.repo
|
|
||||||
when: false # Only enable if you have issues
|
|
||||||
|
|
||||||
- name: Check if EPEL is already installed
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/yum.repos.d/epel.repo
|
|
||||||
register: epel_check
|
|
||||||
|
|
||||||
- name: Install EPEL repo
|
|
||||||
ansible.builtin.dnf:
|
|
||||||
name: epel-release
|
|
||||||
state: present
|
|
||||||
when: not epel_check.stat.exists
|
|
||||||
|
|
||||||
- name: Check if Caddy COPR repo exists
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:group_caddy:caddy.repo
|
|
||||||
register: caddy_repo_check
|
|
||||||
|
|
||||||
- name: Add Caddy COPR repository
|
|
||||||
ansible.builtin.command:
|
|
||||||
cmd: dnf copr enable -y @caddy/caddy
|
|
||||||
when: not caddy_repo_check.stat.exists
|
|
||||||
|
|
||||||
- name: Install all required packages in one transaction
|
|
||||||
ansible.builtin.dnf:
|
|
||||||
state: present
|
|
||||||
name:
|
|
||||||
- caddy
|
|
||||||
- firewalld
|
|
||||||
- htop
|
|
||||||
- rsync
|
|
||||||
- tmux
|
|
||||||
- tar
|
|
||||||
- unzip
|
|
||||||
- python3-libsemanage
|
|
||||||
- python3-policycoreutils
|
|
||||||
- iptables-services
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Enable and start firewalld
|
|
||||||
service:
|
|
||||||
name: firewalld
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
|
|
||||||
- name: Configure firewall for Caddy
|
|
||||||
firewalld:
|
|
||||||
port: "{{ item }}"
|
|
||||||
permanent: yes
|
|
||||||
state: enabled
|
|
||||||
immediate: yes
|
|
||||||
loop:
|
|
||||||
- "80/tcp"
|
|
||||||
- "443/tcp"
|
|
||||||
- "22/tcp"
|
|
||||||
|
|
||||||
- name: Check if Tailscale is installed
|
|
||||||
command: which tailscale
|
|
||||||
register: tailscale_check
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Install Tailscale on AlmaLinux
|
|
||||||
block:
|
|
||||||
- name: Add Tailscale repository
|
|
||||||
yum_repository:
|
|
||||||
name: tailscale-stable
|
|
||||||
description: Tailscale stable
|
|
||||||
baseurl: https://pkgs.tailscale.com/stable/centos/9/$basearch
|
|
||||||
repo_gpgcheck: yes
|
|
||||||
gpgcheck: yes
|
|
||||||
enabled: yes
|
|
||||||
gpgkey: https://pkgs.tailscale.com/stable/centos/9/repo.gpg
|
|
||||||
|
|
||||||
- name: Install Tailscale
|
|
||||||
dnf:
|
|
||||||
name: tailscale
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Enable and start Tailscale daemon
|
|
||||||
service:
|
|
||||||
name: tailscaled
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
when: tailscale_check.rc != 0
|
|
||||||
|
|
||||||
- name: Allow Tailscale through firewall
|
|
||||||
firewalld:
|
|
||||||
port: 41641/udp
|
|
||||||
permanent: yes
|
|
||||||
state: enabled
|
|
||||||
immediate: yes
|
|
||||||
|
|
||||||
- name: Check if Tailscale is already authenticated
|
|
||||||
command: tailscale status --json
|
|
||||||
register: tailscale_status_check
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Authenticate Tailscale
|
|
||||||
command: tailscale up --authkey="{{ tailscale_key }}" --hostname=caddy
|
|
||||||
when:
|
|
||||||
- tailscale_key is defined
|
|
||||||
- tailscale_key != ""
|
|
||||||
- tailscale_status_check.rc != 0 or (tailscale_status_check.stdout | from_json).BackendState != "Running"
|
|
||||||
register: tailscale_auth
|
|
||||||
failed_when: false
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Get Tailscale status
|
|
||||||
command: tailscale status
|
|
||||||
register: tailscale_final_status
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Show final Tailscale status
|
|
||||||
debug:
|
|
||||||
var: tailscale_final_status.stdout_lines
|
|
||||||
|
|
||||||
- name: Enable and start Caddy
|
|
||||||
service:
|
|
||||||
name: caddy
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
|
|
||||||
- name: Deploy Caddyfile configuration
|
|
||||||
template:
|
|
||||||
src: templates/Caddyfile.j2
|
|
||||||
dest: /etc/caddy/Caddyfile
|
|
||||||
owner: caddy
|
|
||||||
group: caddy
|
|
||||||
mode: "0644"
|
|
||||||
backup: yes
|
|
||||||
notify: reload caddy
|
|
||||||
|
|
||||||
- name: SELinux - Allow Caddy to proxy
|
|
||||||
seboolean:
|
|
||||||
name: httpd_can_network_connect
|
|
||||||
state: yes
|
|
||||||
persistent: yes
|
|
||||||
|
|
||||||
- name: SELinux - Allow Caddy to bind to ports
|
|
||||||
seport:
|
|
||||||
ports: "80,443"
|
|
||||||
proto: tcp
|
|
||||||
setype: http_port_t
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Note about SSH forwarding:
|
|
||||||
# Since SSH doesn't support hostname-based routing, you have two options:
|
|
||||||
# 1. Use git.w5isp.com:22 which forwards ALL SSH to Forgejo (can't SSH to caddy directly)
|
|
||||||
# 2. Use different ports: caddy.w5isp.com:22 for server, git.w5isp.com:2222 for git
|
|
||||||
# 3. Configure client-side SSH config to use ProxyJump through caddy server
|
|
||||||
|
|
||||||
- name: Create SSH config info
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
# SSH Configuration for git.w5isp.com
|
|
||||||
#
|
|
||||||
# Since SSH protocol doesn't support hostname-based routing like HTTP,
|
|
||||||
# users need to configure their SSH client to access git properly.
|
|
||||||
#
|
|
||||||
# Add this to your ~/.ssh/config:
|
|
||||||
#
|
|
||||||
# Host git.w5isp.com
|
|
||||||
# ProxyJump caddy.w5isp.com
|
|
||||||
# HostName 100.109.233.14
|
|
||||||
# User git
|
|
||||||
# Port 22
|
|
||||||
#
|
|
||||||
# This allows:
|
|
||||||
# - ssh caddy.w5isp.com → Direct access to caddy server
|
|
||||||
# - ssh git.w5isp.com → Access to Forgejo via ProxyJump
|
|
||||||
# - git clone git@git.w5isp.com:user/repo.git → Works with ProxyJump
|
|
||||||
dest: /etc/ssh/ssh_routing_info.txt
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: reload caddy
|
|
||||||
service:
|
|
||||||
name: caddy
|
|
||||||
state: reloaded
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
---
|
|
||||||
- name: Configure Caddy reverse proxy with Tailscale on Debian 13
|
|
||||||
hosts: vultr
|
|
||||||
become: yes
|
|
||||||
vars:
|
|
||||||
tailscale_key: "{{ lookup('env', 'TAILSCALE_KEY') }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Wait for cloud-init to complete
|
|
||||||
wait_for:
|
|
||||||
path: /var/lib/cloud/instance/boot-finished
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
- name: Check cloud-init status
|
|
||||||
command: cloud-init status --wait
|
|
||||||
register: cloud_init_status
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Show cloud-init status
|
|
||||||
debug:
|
|
||||||
var: cloud_init_status.stdout
|
|
||||||
|
|
||||||
- name: Check if Caddy is installed
|
|
||||||
command: which caddy
|
|
||||||
register: caddy_installed
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Install Caddy if not present
|
|
||||||
apt:
|
|
||||||
name: caddy
|
|
||||||
state: present
|
|
||||||
update_cache: yes
|
|
||||||
when: caddy_installed.rc != 0
|
|
||||||
|
|
||||||
- name: Verify Caddy is installed and running
|
|
||||||
service:
|
|
||||||
name: caddy
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
|
|
||||||
- name: Check if Tailscale is installed
|
|
||||||
command: which tailscale
|
|
||||||
register: tailscale_check
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Install Tailscale on Debian
|
|
||||||
block:
|
|
||||||
- name: Install Tailscale repository key
|
|
||||||
get_url:
|
|
||||||
url: https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg
|
|
||||||
dest: /usr/share/keyrings/tailscale-archive-keyring.gpg
|
|
||||||
|
|
||||||
- name: Add Tailscale repository
|
|
||||||
apt_repository:
|
|
||||||
repo: "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/debian bookworm main"
|
|
||||||
state: present
|
|
||||||
filename: tailscale
|
|
||||||
|
|
||||||
- name: Update apt cache
|
|
||||||
apt:
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Install Tailscale
|
|
||||||
apt:
|
|
||||||
name: tailscale
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Enable and start Tailscale daemon
|
|
||||||
service:
|
|
||||||
name: tailscaled
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
when:
|
|
||||||
- ansible_os_family == "Debian"
|
|
||||||
- tailscale_check.rc != 0
|
|
||||||
|
|
||||||
- name: Verify Tailscale is installed
|
|
||||||
command: tailscale version
|
|
||||||
register: tailscale_version
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Show Tailscale version
|
|
||||||
debug:
|
|
||||||
var: tailscale_version.stdout
|
|
||||||
|
|
||||||
|
|
||||||
- name: Check if Tailscale is already authenticated
|
|
||||||
command: tailscale status --json
|
|
||||||
register: tailscale_status_check
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Restart tailscaled service
|
|
||||||
service:
|
|
||||||
name: tailscaled
|
|
||||||
state: restarted
|
|
||||||
register: restart_result
|
|
||||||
|
|
||||||
- name: Wait for tailscaled to start
|
|
||||||
pause:
|
|
||||||
seconds: 5
|
|
||||||
when: restart_result is changed
|
|
||||||
|
|
||||||
- name: Try to authenticate with explicit socket path
|
|
||||||
command: tailscale --socket=/var/run/tailscale/tailscaled.sock up --authkey="{{ tailscale_key }}" --accept-routes --hostname=caddy
|
|
||||||
when:
|
|
||||||
- tailscale_key is defined
|
|
||||||
- tailscale_key != ""
|
|
||||||
environment:
|
|
||||||
TAILSCALE_SOCKET: /var/run/tailscale/tailscaled.sock
|
|
||||||
register: tailscale_auth
|
|
||||||
failed_when: false
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Debug authentication result
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
RC: {{ tailscale_auth.rc | default('N/A') }}
|
|
||||||
STDOUT: {{ tailscale_auth.stdout | default('') }}
|
|
||||||
STDERR: {{ tailscale_auth.stderr | default('') }}
|
|
||||||
when: tailscale_auth is defined and tailscale_auth is not skipped
|
|
||||||
|
|
||||||
- name: Get Tailscale status
|
|
||||||
command: tailscale --socket=/var/run/tailscale/tailscaled.sock status
|
|
||||||
register: tailscale_final_status
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Show final Tailscale status
|
|
||||||
debug:
|
|
||||||
var: tailscale_final_status.stdout_lines
|
|
||||||
when: tailscale_final_status is defined and tailscale_final_status.stdout_lines is defined
|
|
||||||
|
|
||||||
- name: Show Tailscale setup issue
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
WARNING: Tailscale authentication failed.
|
|
||||||
You may need to manually authenticate Tailscale on this host.
|
|
||||||
|
|
||||||
To debug further, SSH to the host and try:
|
|
||||||
tailscale up --authkey=YOUR_KEY
|
|
||||||
when: tailscale_auth is defined and tailscale_auth is not skipped and tailscale_auth.rc != 0
|
|
||||||
|
|
||||||
- name: Update Caddyfile with any custom configurations
|
|
||||||
template:
|
|
||||||
src: Caddyfile.j2
|
|
||||||
dest: /etc/caddy/Caddyfile
|
|
||||||
owner: caddy
|
|
||||||
group: caddy
|
|
||||||
mode: "0644"
|
|
||||||
backup: yes
|
|
||||||
notify: reload caddy
|
|
||||||
when: false # Disable for now - can be enabled when you have custom configs
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: reload caddy
|
|
||||||
service:
|
|
||||||
name: caddy
|
|
||||||
state: reloaded
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check and Install PostGIS
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check PostgreSQL version
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();"
|
|
||||||
register: pg_version
|
|
||||||
|
|
||||||
- name: Update apt cache in container
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "apt-get update"
|
|
||||||
|
|
||||||
- name: Search for PostGIS packages
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "apt-cache search postgis | grep postgresql"
|
|
||||||
register: postgis_packages
|
|
||||||
|
|
||||||
- name: Display available packages
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL Version:
|
|
||||||
{{ pg_version.stdout }}
|
|
||||||
|
|
||||||
Available PostGIS packages:
|
|
||||||
{{ postgis_packages.stdout }}
|
|
||||||
|
|
||||||
- name: Install PostGIS (flexible version)
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "apt-get install -y postgis"
|
|
||||||
register: install_result
|
|
||||||
|
|
||||||
- name: Enable PostGIS in APRS database
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
|
|
||||||
- name: Display installation result
|
|
||||||
debug:
|
|
||||||
msg: "PostGIS installation completed!"
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check Ceph status on Proxmox
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Check Ceph status
|
|
||||||
command: ceph status
|
|
||||||
register: ceph_status
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display Ceph status
|
|
||||||
debug:
|
|
||||||
var: ceph_status.stdout_lines
|
|
||||||
|
|
||||||
- name: List Ceph pools
|
|
||||||
command: ceph osd pool ls
|
|
||||||
register: ceph_pools
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display Ceph pools
|
|
||||||
debug:
|
|
||||||
msg: "Available pools: {{ ceph_pools.stdout_lines }}"
|
|
||||||
|
|
||||||
- name: List Ceph auth users
|
|
||||||
command: ceph auth ls
|
|
||||||
register: ceph_users
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Check if kubernetes user exists
|
|
||||||
debug:
|
|
||||||
msg: "Kubernetes user exists: {{ 'client.kubernetes' in ceph_users.stdout }}"
|
|
||||||
|
|
||||||
- name: Get Ceph config
|
|
||||||
command: ceph config generate-minimal-conf
|
|
||||||
register: ceph_conf
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display Ceph config
|
|
||||||
debug:
|
|
||||||
var: ceph_conf.stdout_lines
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check PostgreSQL Container 300 Status
|
|
||||||
hosts: lab02
|
|
||||||
gather_facts: no
|
|
||||||
tasks:
|
|
||||||
- name: List PostgreSQL clusters
|
|
||||||
ansible.builtin.command: pct exec 300 -- pg_lsclusters
|
|
||||||
register: pg_clusters
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display PostgreSQL clusters
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: "{{ pg_clusters.stdout_lines }}"
|
|
||||||
|
|
||||||
- name: Check disk space for PostgreSQL
|
|
||||||
ansible.builtin.command: pct exec 300 -- df -h /var/lib/postgresql
|
|
||||||
register: disk_space
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display disk space
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: "{{ disk_space.stdout_lines }}"
|
|
||||||
|
|
||||||
- name: List databases and their sizes
|
|
||||||
ansible.builtin.command: |
|
|
||||||
pct exec 300 -- sudo -u postgres psql -c "SELECT datname, pg_size_pretty(pg_database_size(datname)) as size FROM pg_database ORDER BY pg_database_size(datname) DESC;"
|
|
||||||
register: db_sizes
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display database sizes
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: "{{ db_sizes.stdout_lines }}"
|
|
||||||
|
|
||||||
- name: Check active connections
|
|
||||||
ansible.builtin.command: |
|
|
||||||
pct exec 300 -- sudo -u postgres psql -c "SELECT datname, count(*) as connections FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;"
|
|
||||||
register: active_connections
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display active connections
|
|
||||||
ansible.builtin.debug:
|
|
||||||
msg: "{{ active_connections.stdout_lines }}"
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check PostgreSQL configuration
|
|
||||||
hosts: proxmox
|
|
||||||
become: yes
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Find PostgreSQL version and config location
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
# Check if PostgreSQL is installed
|
|
||||||
which psql || echo 'psql not found'
|
|
||||||
|
|
||||||
# Find PostgreSQL version
|
|
||||||
dpkg -l | grep postgresql-[0-9] | grep -v client || echo 'PostgreSQL package not found'
|
|
||||||
|
|
||||||
# Find pg_hba.conf location
|
|
||||||
find /etc -name pg_hba.conf 2>/dev/null || echo 'pg_hba.conf not found'
|
|
||||||
|
|
||||||
# Check if PostgreSQL is running
|
|
||||||
systemctl status postgresql --no-pager || echo 'PostgreSQL service not found'
|
|
||||||
"
|
|
||||||
register: postgres_info
|
|
||||||
|
|
||||||
- name: Display PostgreSQL information
|
|
||||||
debug:
|
|
||||||
msg: "{{ postgres_info.stdout_lines }}"
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create Ceph keyfile for mounting
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Create kubernetes key file
|
|
||||||
copy:
|
|
||||||
content: "AQAq14Jo/g4ZORAAwxpPOmqj1PYgmih6s6b4vA=="
|
|
||||||
dest: /etc/ceph/client.kubernetes.key
|
|
||||||
mode: '0600'
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup CephFS for Kubernetes shared storage
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
cephfs_name: kubernetes-shared
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if CephFS already exists
|
|
||||||
command: ceph fs ls
|
|
||||||
register: cephfs_list
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display existing CephFS
|
|
||||||
debug:
|
|
||||||
var: cephfs_list.stdout_lines
|
|
||||||
|
|
||||||
- name: Create CephFS data pool if needed
|
|
||||||
command: ceph osd pool create cephfs_kubernetes_data 32
|
|
||||||
register: data_pool
|
|
||||||
failed_when:
|
|
||||||
- data_pool.rc != 0
|
|
||||||
- "'already exists' not in data_pool.stderr"
|
|
||||||
changed_when: data_pool.rc == 0
|
|
||||||
|
|
||||||
- name: Create CephFS metadata pool if needed
|
|
||||||
command: ceph osd pool create cephfs_kubernetes_metadata 16
|
|
||||||
register: metadata_pool
|
|
||||||
failed_when:
|
|
||||||
- metadata_pool.rc != 0
|
|
||||||
- "'already exists' not in metadata_pool.stderr"
|
|
||||||
changed_when: metadata_pool.rc == 0
|
|
||||||
|
|
||||||
- name: Create CephFS if needed
|
|
||||||
command: ceph fs new {{ cephfs_name }} cephfs_kubernetes_metadata cephfs_kubernetes_data
|
|
||||||
register: cephfs_create
|
|
||||||
failed_when:
|
|
||||||
- cephfs_create.rc != 0
|
|
||||||
- "'already exists' not in cephfs_create.stderr"
|
|
||||||
changed_when: cephfs_create.rc == 0
|
|
||||||
|
|
||||||
- name: Get CephFS status
|
|
||||||
command: ceph fs status {{ cephfs_name }}
|
|
||||||
register: cephfs_status
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Display CephFS status
|
|
||||||
debug:
|
|
||||||
var: cephfs_status.stdout_lines
|
|
||||||
when: cephfs_status.rc == 0
|
|
||||||
|
|
||||||
- name: Ensure kubernetes user has CephFS permissions
|
|
||||||
command: |
|
|
||||||
ceph auth caps client.kubernetes mon 'allow r' mds 'allow rw' osd 'allow rw pool=cephfs_kubernetes_data, allow rw pool=cephfs_kubernetes_metadata, allow rw pool=kubernetes'
|
|
||||||
changed_when: false
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create Debian 13 Cloud-Init Template on Proxmox
|
|
||||||
hosts: lab02 # Run on first Proxmox host
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
template_vmid: 9000
|
|
||||||
template_name: "debian-13-cloudinit"
|
|
||||||
storage: "ceph"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if template already exists
|
|
||||||
command: qm status {{ template_vmid }}
|
|
||||||
register: vm_check
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Template creation block
|
|
||||||
when: vm_check.rc != 0
|
|
||||||
block:
|
|
||||||
- name: Download Debian 13 cloud image
|
|
||||||
get_url:
|
|
||||||
url: https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2
|
|
||||||
dest: /var/lib/vz/template/iso/debian-13-generic-amd64.qcow2
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Create VM for template
|
|
||||||
command: qm create {{ template_vmid }} --name {{ template_name }} --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single
|
|
||||||
|
|
||||||
- name: Import disk image
|
|
||||||
command: qm importdisk {{ template_vmid }} /var/lib/vz/template/iso/debian-13-generic-amd64.qcow2 {{ storage }}
|
|
||||||
register: import_result
|
|
||||||
|
|
||||||
- name: Get imported disk name
|
|
||||||
set_fact:
|
|
||||||
imported_disk: "{{ storage }}:vm-{{ template_vmid }}-disk-0"
|
|
||||||
|
|
||||||
- name: Attach imported disk
|
|
||||||
command: qm set {{ template_vmid }} --scsi0 {{ imported_disk }}
|
|
||||||
|
|
||||||
- name: Add cloud-init drive
|
|
||||||
command: qm set {{ template_vmid }} --ide2 {{ storage }}:cloudinit
|
|
||||||
|
|
||||||
- name: Configure boot and display settings
|
|
||||||
command: qm set {{ template_vmid }} --boot c --bootdisk scsi0 --serial0 socket --vga serial0
|
|
||||||
|
|
||||||
- name: Enable QEMU guest agent
|
|
||||||
command: qm set {{ template_vmid }} --agent enabled=1
|
|
||||||
|
|
||||||
- name: Set cloud-init defaults
|
|
||||||
command: qm set {{ template_vmid }} --ipconfig0 ip=dhcp --ciuser debian
|
|
||||||
|
|
||||||
- name: Resize disk to 20G
|
|
||||||
command: qm resize {{ template_vmid }} scsi0 20G
|
|
||||||
|
|
||||||
- name: Convert to template
|
|
||||||
command: qm template {{ template_vmid }}
|
|
||||||
|
|
||||||
- name: Clean up downloaded image
|
|
||||||
file:
|
|
||||||
path: /var/lib/vz/template/iso/debian-13-generic-amd64.qcow2
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: Template ready
|
|
||||||
debug:
|
|
||||||
msg: "Template '{{ template_name }}' (ID: {{ template_vmid }}) is ready on {{ inventory_hostname }}"
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create Forgejo storage directory
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Create Forgejo directory on CephFS
|
|
||||||
file:
|
|
||||||
path: /mnt/cephfs-kubernetes/volumes/forgejo
|
|
||||||
state: directory
|
|
||||||
mode: '0777'
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create MariaDB LXC Container
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 301
|
|
||||||
ct_name: mariadb
|
|
||||||
ct_template: "local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst"
|
|
||||||
ct_memory: 2048 # 2GB RAM
|
|
||||||
ct_disk_size: 50 # 50GB storage
|
|
||||||
ct_cores: 2
|
|
||||||
ct_ip: "10.0.19.6/22"
|
|
||||||
ct_gateway: "10.0.19.254"
|
|
||||||
ct_storage: "ceph" # Use Ceph RBD storage
|
|
||||||
mariadb_root_password: "dOtPgrVnkIW1zwfjvW9rSw"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create MariaDB LXC container
|
|
||||||
command: |
|
|
||||||
pct create {{ ct_id }} {{ ct_template }} \
|
|
||||||
--hostname {{ ct_name }} \
|
|
||||||
--memory {{ ct_memory }} \
|
|
||||||
--cores {{ ct_cores }} \
|
|
||||||
--net0 name=eth0,bridge=vmbr0,ip={{ ct_ip }},gw={{ ct_gateway }} \
|
|
||||||
--storage {{ ct_storage }} \
|
|
||||||
--rootfs {{ ct_storage }}:{{ ct_disk_size }} \
|
|
||||||
--unprivileged 1 \
|
|
||||||
--features nesting=1 \
|
|
||||||
--onboot 1 \
|
|
||||||
--startup order=20
|
|
||||||
|
|
||||||
- name: Start container
|
|
||||||
command: pct start {{ ct_id }}
|
|
||||||
|
|
||||||
- name: Wait for container to boot
|
|
||||||
pause:
|
|
||||||
seconds: 30
|
|
||||||
|
|
||||||
- name: Update container packages
|
|
||||||
shell: pct exec {{ ct_id }} -- apt update && pct exec {{ ct_id }} -- apt upgrade -y
|
|
||||||
|
|
||||||
- name: Install MariaDB
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
apt-get install -y mariadb-server mariadb-client
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Start and enable MariaDB
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
systemctl enable mariadb
|
|
||||||
systemctl start mariadb
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Configure MariaDB for network access
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
# Update bind-address
|
|
||||||
sed -i 's/^bind-address.*=.*/bind-address = 0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
|
|
||||||
|
|
||||||
# Set root password and configure access
|
|
||||||
mysql -u root << 'EOF'
|
|
||||||
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('{{ mariadb_root_password }}');
|
|
||||||
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mariadb_root_password }}';
|
|
||||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Restart MariaDB
|
|
||||||
systemctl restart mariadb
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Save credentials to file
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
MariaDB Container Credentials
|
|
||||||
=============================
|
|
||||||
Container ID: {{ ct_id }}
|
|
||||||
Host: lab02
|
|
||||||
IP Address: 10.0.19.6
|
|
||||||
Port: 3306
|
|
||||||
|
|
||||||
Root Credentials:
|
|
||||||
Username: root
|
|
||||||
Password: {{ mariadb_root_password }}
|
|
||||||
|
|
||||||
Connection String:
|
|
||||||
mysql -h 10.0.19.6 -u root -p'{{ mariadb_root_password }}'
|
|
||||||
|
|
||||||
Note: This container was created on {{ ansible_date_time.iso8601 }}
|
|
||||||
dest: "./mariadb_credentials.txt"
|
|
||||||
mode: '0600'
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Display connection info
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
MariaDB container created successfully!
|
|
||||||
|
|
||||||
Container details:
|
|
||||||
- Container ID: {{ ct_id }}
|
|
||||||
- Host: lab02
|
|
||||||
- IP: 10.0.19.6
|
|
||||||
- Storage: {{ ct_disk_size }}GB on {{ ct_storage }}
|
|
||||||
|
|
||||||
Root credentials:
|
|
||||||
- Username: root
|
|
||||||
- Password: {{ mariadb_root_password }}
|
|
||||||
|
|
||||||
Credentials saved to: ./mariadb_credentials.txt
|
|
||||||
|
|
@ -1,216 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create PostgreSQL 17 LXC Container with Debian 13 on lab02
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
ct_name: postgres
|
|
||||||
ct_template: "local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst"
|
|
||||||
ct_memory: 8192 # 8GB RAM
|
|
||||||
ct_disk_size: 512 # 512GB storage as requested
|
|
||||||
ct_cores: 4
|
|
||||||
ct_ip: "10.0.19.5/22"
|
|
||||||
ct_gateway: "10.0.19.254"
|
|
||||||
ct_storage: "ceph" # Use Ceph RBD storage
|
|
||||||
aprs_password: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=16') }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if container already exists
|
|
||||||
command: pct status {{ ct_id }}
|
|
||||||
register: ct_exists
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Stop and destroy existing container if it exists
|
|
||||||
shell: |
|
|
||||||
pct stop {{ ct_id }} || true
|
|
||||||
pct destroy {{ ct_id }} --purge || true
|
|
||||||
when: ct_exists.rc == 0
|
|
||||||
|
|
||||||
- name: List available templates
|
|
||||||
command: pveam list local
|
|
||||||
register: template_list
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Show available templates
|
|
||||||
debug:
|
|
||||||
msg: "Available templates: {{ template_list.stdout_lines | select('match', '.*debian.*') | list }}"
|
|
||||||
|
|
||||||
- name: Create PostgreSQL LXC container
|
|
||||||
command: |
|
|
||||||
pct create {{ ct_id }} {{ ct_template }} \
|
|
||||||
--hostname {{ ct_name }} \
|
|
||||||
--memory {{ ct_memory }} \
|
|
||||||
--cores {{ ct_cores }} \
|
|
||||||
--net0 name=eth0,bridge=vmbr0,ip={{ ct_ip }},gw={{ ct_gateway }} \
|
|
||||||
--storage {{ ct_storage }} \
|
|
||||||
--rootfs {{ ct_storage }}:{{ ct_disk_size }} \
|
|
||||||
--unprivileged 1 \
|
|
||||||
--features nesting=1 \
|
|
||||||
--onboot 1 \
|
|
||||||
--startup order=10
|
|
||||||
|
|
||||||
- name: Start container
|
|
||||||
command: pct start {{ ct_id }}
|
|
||||||
|
|
||||||
- name: Wait for container to boot
|
|
||||||
pause:
|
|
||||||
seconds: 30
|
|
||||||
|
|
||||||
- name: Update container packages
|
|
||||||
shell: pct exec {{ ct_id }} -- apt update && pct exec {{ ct_id }} -- apt upgrade -y
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 17 repository
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
apt-get install -y wget ca-certificates
|
|
||||||
sh -c 'echo \"deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\" > /etc/apt/sources.list.d/pgdg.list'
|
|
||||||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
|
||||||
apt-get update
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 17 and PostGIS
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
apt-get install -y postgresql-17 postgresql-contrib-17 postgresql-17-postgis-3 postgis
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Start and enable PostgreSQL
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
systemctl enable postgresql
|
|
||||||
systemctl start postgresql
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Configure PostgreSQL for network access
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
# Configure postgresql.conf
|
|
||||||
sed -i \"s/#listen_addresses = 'localhost'/listen_addresses = '*'/g\" /etc/postgresql/17/main/postgresql.conf
|
|
||||||
|
|
||||||
# Configure pg_hba.conf
|
|
||||||
echo '# TYPE DATABASE USER ADDRESS METHOD' > /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'local all postgres peer' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'local all all peer' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all 127.0.0.1/32 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all ::1/128 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.0.19.0/24 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.0.16.0/22 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.42.0.0/16 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.43.0.0/16 scram-sha-256' >> /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
|
|
||||||
# Restart PostgreSQL
|
|
||||||
systemctl restart postgresql
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Create APRS user and database
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- su - postgres -c "psql << 'EOF'
|
|
||||||
-- Create APRS user and database
|
|
||||||
CREATE USER aprs WITH PASSWORD '{{ aprs_password }}';
|
|
||||||
CREATE DATABASE aprs OWNER aprs;
|
|
||||||
\c aprs
|
|
||||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE aprs TO aprs;
|
|
||||||
GRANT ALL ON SCHEMA public TO aprs;
|
|
||||||
ALTER DATABASE aprs SET search_path TO public, postgis;
|
|
||||||
EOF"
|
|
||||||
|
|
||||||
- name: Test APRS database connection
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- su - postgres -c "psql -d aprs -c 'SELECT version(); SELECT PostGIS_full_version();'"
|
|
||||||
register: db_test
|
|
||||||
|
|
||||||
- name: Save APRS password to file
|
|
||||||
copy:
|
|
||||||
content: "{{ aprs_password }}"
|
|
||||||
dest: "./aprs_db_password.txt"
|
|
||||||
mode: '0600'
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Display connection info
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL 17 with PostGIS installed successfully on Debian 13!
|
|
||||||
|
|
||||||
Container details:
|
|
||||||
- Container ID: {{ ct_id }}
|
|
||||||
- Host: lab02
|
|
||||||
- IP: 10.0.19.5
|
|
||||||
- Storage: {{ ct_disk_size }}GB on {{ ct_storage }}
|
|
||||||
|
|
||||||
Database details:
|
|
||||||
- PostgreSQL version: 17
|
|
||||||
- PostGIS: Installed
|
|
||||||
- Database: aprs
|
|
||||||
- User: aprs
|
|
||||||
- Password: {{ aprs_password }}
|
|
||||||
- Password saved to: ./aprs_db_password.txt
|
|
||||||
|
|
||||||
Connection string:
|
|
||||||
postgresql://aprs:{{ aprs_password }}@10.0.19.5:5432/aprs
|
|
||||||
|
|
||||||
Test output:
|
|
||||||
{{ db_test.stdout }}
|
|
||||||
|
|
||||||
- name: Create K8s secret for APRS database
|
|
||||||
hosts: home-k3s-control-1
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
aprs_password: "{{ hostvars['lab02']['aprs_password'] }}"
|
|
||||||
tasks:
|
|
||||||
- name: Create aprs namespace if it doesn't exist
|
|
||||||
command: |
|
|
||||||
/usr/local/bin/k3s kubectl create namespace aprs --dry-run=client -o yaml | /usr/local/bin/k3s kubectl apply -f -
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Delete existing database secret if it exists
|
|
||||||
command: |
|
|
||||||
/usr/local/bin/k3s kubectl delete secret aprs-db-secret -n aprs --ignore-not-found=true
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Create database secret
|
|
||||||
command: |
|
|
||||||
/usr/local/bin/k3s kubectl create secret generic aprs-db-secret \
|
|
||||||
--from-literal=DATABASE_URL="ecto://aprs:{{ aprs_password }}@10.0.19.5:5432/aprs" \
|
|
||||||
--from-literal=DB_HOST="10.0.19.5" \
|
|
||||||
--from-literal=DB_PORT="5432" \
|
|
||||||
--from-literal=DB_NAME="aprs" \
|
|
||||||
--from-literal=DB_USER="aprs" \
|
|
||||||
--from-literal=DB_PASSWORD="{{ aprs_password }}" \
|
|
||||||
-n aprs
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Verify secret was created
|
|
||||||
command: |
|
|
||||||
/usr/local/bin/k3s kubectl get secret aprs-db-secret -n aprs -o yaml
|
|
||||||
register: secret_verify
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Display secret creation result
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
Kubernetes secret created successfully!
|
|
||||||
|
|
||||||
Secret name: aprs-db-secret
|
|
||||||
Namespace: aprs
|
|
||||||
|
|
||||||
To use in your deployment, add:
|
|
||||||
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
name: aprs-db-secret
|
|
||||||
|
|
||||||
Or individual env vars:
|
|
||||||
|
|
||||||
env:
|
|
||||||
- name: DATABASE_URL
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: aprs-db-secret
|
|
||||||
key: DATABASE_URL
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create PostgreSQL LXC Container on Proxmox
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
ct_name: postgres
|
|
||||||
ct_template: "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
|
|
||||||
ct_memory: 8192 # 8GB RAM
|
|
||||||
ct_disk_size: 1024 # 1TB storage
|
|
||||||
ct_cores: 4
|
|
||||||
ct_ip: "10.0.19.5/22"
|
|
||||||
ct_gateway: "10.0.19.254"
|
|
||||||
ct_storage: "ceph" # Use Ceph storage
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if container already exists
|
|
||||||
command: pct status {{ ct_id }}
|
|
||||||
register: ct_exists
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Create PostgreSQL LXC container
|
|
||||||
command: |
|
|
||||||
pct create {{ ct_id }} {{ ct_template }} \
|
|
||||||
--hostname {{ ct_name }} \
|
|
||||||
--memory {{ ct_memory }} \
|
|
||||||
--cores {{ ct_cores }} \
|
|
||||||
--net0 name=eth0,bridge=vmbr0,ip={{ ct_ip }},gw={{ ct_gateway }} \
|
|
||||||
--storage {{ ct_storage }} \
|
|
||||||
--rootfs {{ ct_storage }}:{{ ct_disk_size }} \
|
|
||||||
--unprivileged 1 \
|
|
||||||
--features nesting=1 \
|
|
||||||
--onboot 1 \
|
|
||||||
--startup order=10
|
|
||||||
when: ct_exists.rc != 0
|
|
||||||
|
|
||||||
- name: Start container
|
|
||||||
command: pct start {{ ct_id }}
|
|
||||||
when: ct_exists.rc != 0
|
|
||||||
|
|
||||||
- name: Wait for container to be ready
|
|
||||||
wait_for:
|
|
||||||
host: 10.0.19.5
|
|
||||||
port: 22
|
|
||||||
timeout: 60
|
|
||||||
delay: 10
|
|
||||||
when: ct_exists.rc != 0
|
|
||||||
|
|
||||||
- name: Update container packages
|
|
||||||
shell: pct exec {{ ct_id }} -- apt update && pct exec {{ ct_id }} -- apt upgrade -y
|
|
||||||
when: ct_exists.rc != 0
|
|
||||||
|
|
||||||
- name: Display container info
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL LXC Container created:
|
|
||||||
- ID: {{ ct_id }}
|
|
||||||
- Name: {{ ct_name }}
|
|
||||||
- IP: 10.0.19.5
|
|
||||||
- RAM: {{ ct_memory }}MB
|
|
||||||
- Storage: {{ ct_disk_size }}GB
|
|
||||||
- Cores: {{ ct_cores }}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create PostgreSQL storage directory
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Create PostgreSQL directory on CephFS
|
|
||||||
file:
|
|
||||||
path: /mnt/cephfs-kubernetes/volumes/postgresql
|
|
||||||
state: directory
|
|
||||||
mode: '0700'
|
|
||||||
owner: '999' # PostgreSQL container user
|
|
||||||
group: '999'
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
---
|
|
||||||
- name: Create RBD volumes on Proxmox Ceph
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
volumes:
|
|
||||||
- name: adguard-config
|
|
||||||
size: 2G
|
|
||||||
- name: adguard-data
|
|
||||||
size: 10G
|
|
||||||
- name: nodered-data
|
|
||||||
size: 5G
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create RBD volumes
|
|
||||||
shell: |
|
|
||||||
rbd create kubernetes/{{ item.name }} --size {{ item.size }} --image-feature layering
|
|
||||||
loop: "{{ volumes }}"
|
|
||||||
register: rbd_create
|
|
||||||
failed_when:
|
|
||||||
- rbd_create.rc != 0
|
|
||||||
- "'already exists' not in rbd_create.stderr"
|
|
||||||
changed_when: rbd_create.rc == 0
|
|
||||||
|
|
||||||
- name: List created volumes
|
|
||||||
command: rbd ls kubernetes
|
|
||||||
register: rbd_list
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display volumes
|
|
||||||
debug:
|
|
||||||
msg: "Created volumes in kubernetes pool: {{ rbd_list.stdout_lines }}"
|
|
||||||
|
|
||||||
- name: Get volume info
|
|
||||||
shell: |
|
|
||||||
rbd info kubernetes/{{ item.name }} --format json
|
|
||||||
loop: "{{ volumes }}"
|
|
||||||
register: volume_info
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display volume details
|
|
||||||
debug:
|
|
||||||
msg: "Volume {{ item.item.name }}: {{ (item.stdout | from_json).size | int / 1024 / 1024 / 1024 }}GB"
|
|
||||||
loop: "{{ volume_info.results }}"
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
---
|
|
||||||
- name: Deploy Ceph CSI for direct RBD access
|
|
||||||
hosts: localhost
|
|
||||||
connection: local
|
|
||||||
vars:
|
|
||||||
kubeconfig: "{{ playbook_dir }}/kubeconfig"
|
|
||||||
ceph_csi_dir: "../cluster/ceph-csi"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create temporary directory for fixed configs
|
|
||||||
tempfile:
|
|
||||||
state: directory
|
|
||||||
register: temp_dir
|
|
||||||
|
|
||||||
- name: Copy original kustomization.yaml
|
|
||||||
copy:
|
|
||||||
src: "{{ ceph_csi_dir }}/kustomization.yaml"
|
|
||||||
dest: "{{ temp_dir.path }}/kustomization.yaml"
|
|
||||||
|
|
||||||
- name: Update kustomization to use fixed files
|
|
||||||
replace:
|
|
||||||
path: "{{ temp_dir.path }}/kustomization.yaml"
|
|
||||||
regexp: "{{ item.old }}"
|
|
||||||
replace: "{{ item.new }}"
|
|
||||||
loop:
|
|
||||||
- { old: "csi-rbdplugin.yaml", new: "csi-rbdplugin-fixed.yaml" }
|
|
||||||
- { old: "csi-rbdplugin-provisioner.yaml", new: "csi-rbdplugin-provisioner-fixed.yaml" }
|
|
||||||
- { old: "ceph-config.yaml", new: "ceph-config-fixed.yaml" }
|
|
||||||
|
|
||||||
- name: Copy all required files to temp directory
|
|
||||||
copy:
|
|
||||||
src: "{{ ceph_csi_dir }}/{{ item }}"
|
|
||||||
dest: "{{ temp_dir.path }}/{{ item }}"
|
|
||||||
loop:
|
|
||||||
- namespace.yaml
|
|
||||||
- ceph-csi-configmap.yaml
|
|
||||||
- ceph-csi-secret.yaml
|
|
||||||
- ceph-csi-rbd-driver.yaml
|
|
||||||
- csi-driver.yaml
|
|
||||||
- ceph-storageclass.yaml
|
|
||||||
- csi-rbdplugin-fixed.yaml
|
|
||||||
- csi-rbdplugin-provisioner-fixed.yaml
|
|
||||||
- ceph-config-fixed.yaml
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Check if namespace exists
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl get namespace ceph-csi
|
|
||||||
register: ns_check
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Delete existing Ceph CSI deployment if exists
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl delete daemonset,deployment,service -n ceph-csi -l app in (csi-rbdplugin,csi-rbdplugin-provisioner,csi-metrics) --ignore-not-found
|
|
||||||
when: ns_check.rc == 0
|
|
||||||
|
|
||||||
- name: Wait for pods to terminate
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl wait --for=delete pod -n ceph-csi -l app in (csi-rbdplugin,csi-rbdplugin-provisioner) --timeout=60s || true
|
|
||||||
when: ns_check.rc == 0
|
|
||||||
|
|
||||||
- name: Apply Ceph CSI configuration
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl apply -k {{ temp_dir.path }}
|
|
||||||
register: apply_result
|
|
||||||
|
|
||||||
- name: Display apply result
|
|
||||||
debug:
|
|
||||||
var: apply_result.stdout_lines
|
|
||||||
|
|
||||||
- name: Wait for CSI pods to be ready
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl wait --for=condition=ready pod -n ceph-csi -l app=csi-rbdplugin-provisioner --timeout=300s || true
|
|
||||||
kubectl wait --for=condition=ready pod -n ceph-csi -l app=csi-rbdplugin --timeout=300s || true
|
|
||||||
register: wait_result
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Check CSI pod status
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
echo "=== CSI Provisioner Pods ==="
|
|
||||||
kubectl get pods -n ceph-csi -l app=csi-rbdplugin-provisioner
|
|
||||||
echo -e "\n=== CSI Node Plugin Pods ==="
|
|
||||||
kubectl get pods -n ceph-csi -l app=csi-rbdplugin
|
|
||||||
echo -e "\n=== Storage Class ==="
|
|
||||||
kubectl get storageclass ceph-rbd
|
|
||||||
register: status_check
|
|
||||||
|
|
||||||
- name: Display CSI status
|
|
||||||
debug:
|
|
||||||
var: status_check.stdout_lines
|
|
||||||
|
|
||||||
- name: Clean up temporary directory
|
|
||||||
file:
|
|
||||||
path: "{{ temp_dir.path }}"
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: Test Ceph CSI with a sample PVC
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
cat <<EOF | kubectl apply -f -
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: test-ceph-pvc
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
storageClassName: ceph-rbd
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 1Gi
|
|
||||||
EOF
|
|
||||||
register: test_pvc
|
|
||||||
|
|
||||||
- name: Check test PVC status
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
sleep 5
|
|
||||||
kubectl get pvc test-ceph-pvc
|
|
||||||
register: pvc_status
|
|
||||||
|
|
||||||
- name: Display test PVC status
|
|
||||||
debug:
|
|
||||||
var: pvc_status.stdout_lines
|
|
||||||
|
|
||||||
- name: Clean up test PVC
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl delete pvc test-ceph-pvc --ignore-not-found
|
|
||||||
when: test_pvc is succeeded
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
---
|
|
||||||
- name: Deploy MariaDB LXC Container on Proxmox
|
|
||||||
hosts: proxmox
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
container_id: 301
|
|
||||||
container_hostname: mariadb
|
|
||||||
container_template: "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
|
|
||||||
container_cores: 2
|
|
||||||
container_memory: 4096
|
|
||||||
container_storage: 50
|
|
||||||
container_ip: "10.0.19.6/24"
|
|
||||||
container_gateway: "10.0.19.254"
|
|
||||||
container_nameserver: "9.9.9.9"
|
|
||||||
container_password: "{{ lookup('password', '/dev/null length=20 chars=ascii_letters,digits') }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if container already exists
|
|
||||||
shell: pct status {{ container_id }}
|
|
||||||
register: container_status
|
|
||||||
ignore_errors: yes
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Create MariaDB LXC container
|
|
||||||
shell: |
|
|
||||||
pct create {{ container_id }} {{ container_template }} \
|
|
||||||
--hostname {{ container_hostname }} \
|
|
||||||
--cores {{ container_cores }} \
|
|
||||||
--memory {{ container_memory }} \
|
|
||||||
--storage ceph \
|
|
||||||
--rootfs ceph:{{ container_storage }} \
|
|
||||||
--net0 name=eth0,bridge=vmbr0,ip={{ container_ip }},gw={{ container_gateway }} \
|
|
||||||
--nameserver {{ container_nameserver }} \
|
|
||||||
--password {{ container_password }} \
|
|
||||||
--unprivileged 1 \
|
|
||||||
--features nesting=1 \
|
|
||||||
--ostype debian
|
|
||||||
when: container_status.rc != 0
|
|
||||||
|
|
||||||
- name: Start the container
|
|
||||||
shell: pct start {{ container_id }}
|
|
||||||
when: container_status.rc != 0
|
|
||||||
|
|
||||||
- name: Wait for container to be ready
|
|
||||||
pause:
|
|
||||||
seconds: 30
|
|
||||||
when: container_status.rc != 0
|
|
||||||
|
|
||||||
- name: Update container and install MariaDB
|
|
||||||
shell: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y mariadb-server mariadb-client
|
|
||||||
systemctl enable mariadb
|
|
||||||
systemctl start mariadb
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Secure MariaDB installation
|
|
||||||
shell: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
mysql -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY 'mariadb_root_2024';\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"DELETE FROM mysql.user WHERE User='';\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"DROP DATABASE IF EXISTS test;\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"FLUSH PRIVILEGES;\"
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Configure MariaDB for network access
|
|
||||||
shell: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
|
|
||||||
systemctl restart mariadb
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Configure firewall
|
|
||||||
shell: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
apt-get install -y ufw
|
|
||||||
ufw allow 3306/tcp
|
|
||||||
ufw --force enable
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Create Ghost database and user
|
|
||||||
shell: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"CREATE DATABASE IF NOT EXISTS ghost CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"CREATE USER IF NOT EXISTS 'ghost'@'%' IDENTIFIED BY 'ghost_db_password_2024';\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"GRANT ALL PRIVILEGES ON ghost.* TO 'ghost'@'%';\"
|
|
||||||
mysql -uroot -pmariadb_root_2024 -e \"FLUSH PRIVILEGES;\"
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Display container information
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "MariaDB container created successfully!"
|
|
||||||
- "Container ID: {{ container_id }}"
|
|
||||||
- "IP Address: 10.0.19.6"
|
|
||||||
- "Root password: mariadb_root_2024"
|
|
||||||
- "Ghost database: ghost"
|
|
||||||
- "Ghost user: ghost"
|
|
||||||
- "Ghost password: ghost_db_password_2024"
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
- name: Download Debian 13 LXC template
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Update template list
|
|
||||||
command: pveam update
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Search for Debian 13 template
|
|
||||||
command: pveam available | grep -i "debian-13"
|
|
||||||
register: debian13_search
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Show available Debian 13 templates
|
|
||||||
debug:
|
|
||||||
var: debian13_search.stdout_lines
|
|
||||||
when: debian13_search.rc == 0
|
|
||||||
|
|
||||||
- name: Download Debian 12 template (if 13 not available)
|
|
||||||
command: pveam download local debian-12-standard_12.7-1_amd64.tar.zst
|
|
||||||
register: download_result
|
|
||||||
failed_when: false
|
|
||||||
changed_when: "'already exists' not in download_result.stderr"
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
- name: Enable PostGIS Extension
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Try to enable PostGIS extension
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
register: postgis_enable
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Install PostGIS for PostgreSQL 15 if extension failed
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "apt-get install -y postgresql-15-postgis-3 || apt-get install -y postgis postgresql-postgis"
|
|
||||||
when: postgis_enable.rc != 0
|
|
||||||
register: install_result
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Try to enable PostGIS again if it was just installed
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
when: postgis_enable.rc != 0
|
|
||||||
|
|
||||||
- name: Show results
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
{% if postgis_enable.rc == 0 %}
|
|
||||||
PostGIS extension enabled successfully!
|
|
||||||
{% else %}
|
|
||||||
PostGIS installation attempt: {{ install_result.stderr | default('') }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
---
|
|
||||||
- name: Enable PostGIS in APRS Database
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if PostGIS is installed
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- dpkg -l | grep postgis
|
|
||||||
register: postgis_check
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Install PostGIS if not present
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3 postgresql-16-postgis-3-scripts
|
|
||||||
when: postgis_check.rc != 0
|
|
||||||
|
|
||||||
- name: Enable PostGIS extension in APRS database
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
register: postgis_result
|
|
||||||
|
|
||||||
- name: Enable PostGIS topology extension
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;"
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Verify PostGIS installation
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();"
|
|
||||||
register: postgis_version
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display results
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostGIS setup completed!
|
|
||||||
|
|
||||||
Extension creation: {{ postgis_result.stdout | default('Done') }}
|
|
||||||
{% if postgis_version.rc == 0 %}
|
|
||||||
PostGIS Version: {{ postgis_version.stdout }}
|
|
||||||
{% else %}
|
|
||||||
Note: PostGIS may require package installation
|
|
||||||
{% endif %}
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
---
|
|
||||||
- name: Fix NFS permissions for all users write access
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
nfs_export_path: /mnt/cephfs-kubernetes
|
|
||||||
k8s_network: "10.0.19.0/24"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Update NFS export configuration for better access
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/exports
|
|
||||||
line: "{{ nfs_export_path }} {{ k8s_network }}(rw,sync,no_subtree_check,no_root_squash,no_all_squash)"
|
|
||||||
regexp: "^{{ nfs_export_path | regex_escape() }}\\s+"
|
|
||||||
create: yes
|
|
||||||
backup: yes
|
|
||||||
notify:
|
|
||||||
- restart nfs
|
|
||||||
- export nfs shares
|
|
||||||
|
|
||||||
- name: Ensure base directories have proper permissions
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}/{{ item }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0777'
|
|
||||||
loop:
|
|
||||||
- volumes
|
|
||||||
- shared
|
|
||||||
|
|
||||||
- name: Set world-writable permissions on general storage directories
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}/{{ item }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0777'
|
|
||||||
loop:
|
|
||||||
- volumes/adguard
|
|
||||||
- volumes/nodered
|
|
||||||
- volumes/forgejo
|
|
||||||
- shared
|
|
||||||
ignore_errors: yes # In case some don't exist yet
|
|
||||||
|
|
||||||
- name: Preserve PostgreSQL specific permissions
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}/volumes/postgresql"
|
|
||||||
state: directory
|
|
||||||
owner: '999'
|
|
||||||
group: '999'
|
|
||||||
mode: '0700'
|
|
||||||
recurse: yes
|
|
||||||
when: ansible_check_mode or (nfs_export_path + "/volumes/postgresql") is directory
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Set sticky bit on shared directories
|
|
||||||
command: chmod +t {{ nfs_export_path }}/{{ item }}
|
|
||||||
loop:
|
|
||||||
- volumes
|
|
||||||
- shared
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current exports
|
|
||||||
command: exportfs -v
|
|
||||||
register: exports_output
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Show current exports
|
|
||||||
debug:
|
|
||||||
var: exports_output.stdout_lines
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart nfs
|
|
||||||
service:
|
|
||||||
name: nfs-kernel-server
|
|
||||||
state: restarted
|
|
||||||
|
|
||||||
- name: export nfs shares
|
|
||||||
command: exportfs -ra
|
|
||||||
changed_when: false
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
- name: Fix PostgreSQL pg_hba.conf for K3s access
|
|
||||||
hosts: proxmox
|
|
||||||
become: yes
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Update pg_hba.conf to allow K3s nodes
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
# Backup current pg_hba.conf
|
|
||||||
cp /etc/postgresql/16/main/pg_hba.conf /etc/postgresql/16/main/pg_hba.conf.backup
|
|
||||||
|
|
||||||
# Check if K3s network entry exists
|
|
||||||
if ! grep -q '10.0.19.0/24' /etc/postgresql/16/main/pg_hba.conf; then
|
|
||||||
# Add K3s network access
|
|
||||||
echo 'host all all 10.0.19.0/24 md5' >> /etc/postgresql/16/main/pg_hba.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Reload PostgreSQL
|
|
||||||
systemctl reload postgresql
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Verify pg_hba.conf entries
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- grep '10.0.19' /etc/postgresql/16/main/pg_hba.conf
|
|
||||||
register: hba_entries
|
|
||||||
|
|
||||||
- name: Display pg_hba.conf entries
|
|
||||||
debug:
|
|
||||||
msg: "{{ hba_entries.stdout_lines }}"
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
---
|
|
||||||
- name: Fix PostgreSQL directory permissions
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Fix PostgreSQL directory ownership
|
|
||||||
file:
|
|
||||||
path: /mnt/cephfs-kubernetes/volumes/postgresql
|
|
||||||
state: directory
|
|
||||||
owner: '999'
|
|
||||||
group: '999'
|
|
||||||
mode: '0700'
|
|
||||||
recurse: yes
|
|
||||||
|
|
||||||
- name: Ensure write permissions
|
|
||||||
command: chmod -R 700 /mnt/cephfs-kubernetes/volumes/postgresql
|
|
||||||
changed_when: false
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
Forgejo Database Credentials
|
|
||||||
============================
|
|
||||||
|
|
||||||
PostgreSQL Container: 300 on lab02
|
|
||||||
Host: 10.0.19.5
|
|
||||||
Port: 5432
|
|
||||||
Database: forgejo
|
|
||||||
Username: forgejo
|
|
||||||
Password: 6Cj1BR1zgutXn0LzDCvanw
|
|
||||||
|
|
||||||
Connection String:
|
|
||||||
postgresql://forgejo:6Cj1BR1zgutXn0LzDCvanw@10.0.19.5:5432/forgejo
|
|
||||||
|
|
||||||
For Forgejo app.ini configuration:
|
|
||||||
[database]
|
|
||||||
DB_TYPE = postgres
|
|
||||||
HOST = 10.0.19.5:5432
|
|
||||||
NAME = forgejo
|
|
||||||
USER = forgejo
|
|
||||||
PASSWD = 6Cj1BR1zgutXn0LzDCvanw
|
|
||||||
SSL_MODE = disable
|
|
||||||
|
|
||||||
Note: The password has also been saved to /tmp/forgejo_db_password.txt
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
- name: Get Ceph kubernetes user key
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Get kubernetes user auth
|
|
||||||
command: ceph auth get client.kubernetes
|
|
||||||
register: k8s_auth
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display kubernetes auth
|
|
||||||
debug:
|
|
||||||
var: k8s_auth.stdout_lines
|
|
||||||
|
|
||||||
- name: Extract just the key
|
|
||||||
command: ceph auth print-key client.kubernetes
|
|
||||||
register: k8s_key
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display key
|
|
||||||
debug:
|
|
||||||
msg: "Kubernetes key: {{ k8s_key.stdout }}"
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
---
|
|
||||||
- name: Install Ceph client packages on K3s nodes
|
|
||||||
hosts: k3s_cluster
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Update apt cache
|
|
||||||
apt:
|
|
||||||
update_cache: yes
|
|
||||||
cache_valid_time: 3600
|
|
||||||
when: ansible_os_family == "Debian"
|
|
||||||
|
|
||||||
- name: Install ceph-common package
|
|
||||||
package:
|
|
||||||
name: ceph-common
|
|
||||||
state: present
|
|
||||||
register: ceph_install
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Check if ceph-common is installed
|
|
||||||
command: which ceph
|
|
||||||
register: ceph_check
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display ceph installation status
|
|
||||||
debug:
|
|
||||||
msg: "Ceph client installed: {{ ceph_check.rc == 0 }}"
|
|
||||||
|
|
||||||
- name: Create ceph configuration directory
|
|
||||||
file:
|
|
||||||
path: /etc/ceph
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Load RBD kernel module
|
|
||||||
modprobe:
|
|
||||||
name: rbd
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Persist RBD module
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/modules-load.d/ceph.conf
|
|
||||||
line: rbd
|
|
||||||
create: yes
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
- name: Install NFS client on K3s nodes
|
|
||||||
hosts: k3s_cluster
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Install NFS client packages
|
|
||||||
package:
|
|
||||||
name: nfs-common
|
|
||||||
state: present
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
---
|
|
||||||
- name: Install PostGIS in PostgreSQL LXC
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Update apt cache
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get update
|
|
||||||
|
|
||||||
- name: Install PostGIS package
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3
|
|
||||||
|
|
||||||
- name: Enable PostGIS extension in APRS database
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
|
|
||||||
- name: Enable PostGIS topology extension
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;"
|
|
||||||
|
|
||||||
- name: Verify PostGIS installation
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();"
|
|
||||||
register: postgis_version
|
|
||||||
|
|
||||||
- name: Display PostGIS version
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostGIS has been installed successfully!
|
|
||||||
|
|
||||||
Version: {{ postgis_version.stdout }}
|
|
||||||
|
|
||||||
The APRS database now has spatial capabilities for location data.
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
all:
|
|
||||||
children:
|
|
||||||
proxmox:
|
|
||||||
hosts:
|
|
||||||
lab02:
|
|
||||||
ansible_host: 10.0.16.231
|
|
||||||
lab03:
|
|
||||||
ansible_host: 10.0.16.232
|
|
||||||
lab04:
|
|
||||||
ansible_host: 10.0.16.233
|
|
||||||
vars:
|
|
||||||
ansible_user: root
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
k3s_cluster:
|
|
||||||
children:
|
|
||||||
k3s_control:
|
|
||||||
hosts:
|
|
||||||
home-k3s-control-1:
|
|
||||||
ansible_host: 10.0.19.100
|
|
||||||
k3s_control_node: true
|
|
||||||
home-k3s-control-2:
|
|
||||||
ansible_host: 10.0.19.101
|
|
||||||
k3s_control_node: true
|
|
||||||
home-k3s-control-3:
|
|
||||||
ansible_host: 10.0.19.102
|
|
||||||
k3s_control_node: true
|
|
||||||
k3s_workers:
|
|
||||||
hosts:
|
|
||||||
home-k3s-worker-1:
|
|
||||||
ansible_host: 10.0.19.110
|
|
||||||
home-k3s-worker-2:
|
|
||||||
ansible_host: 10.0.19.111
|
|
||||||
home-k3s-worker-3:
|
|
||||||
ansible_host: 10.0.19.112
|
|
||||||
vars:
|
|
||||||
ansible_user: debian
|
|
||||||
ansible_ssh_private_key_file: "~/.ssh/id_rsa"
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
|
|
||||||
k3s_version: v1.28.5+k3s1
|
|
||||||
caddy_servers:
|
|
||||||
hosts:
|
|
||||||
caddy:
|
|
||||||
ansible_host: 204.110.191.212
|
|
||||||
vars:
|
|
||||||
ansible_user: ansible # Now using ansible user after bootstrap
|
|
||||||
ansible_ssh_private_key_file: "~/.ssh/ansible"
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
|
|
||||||
postgresql:
|
|
||||||
hosts:
|
|
||||||
postgres-lxc:
|
|
||||||
ansible_host: 10.0.19.5
|
|
||||||
vars:
|
|
||||||
ansible_user: root # LXC containers typically use root
|
|
||||||
ansible_ssh_private_key_file: "~/.ssh/id_rsa" # Try default key
|
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
|
||||||
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
clusters:
|
|
||||||
- cluster:
|
|
||||||
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUzTlRnek9EUXdOakV3SGhjTk1qVXdPVEl3TVRZd01UQXhXaGNOTXpVd09URTRNVFl3TVRBeApXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUzTlRnek9EUXdOakV3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFUMUwxRHNza3prWmd5VGVuY1lISjhrdTJkZXF0WmF0VWJzbm1DVFRobHQKSWN1a3VKRkhNTENtZzN3VzdqM3BjRU90Z3Q0TUVUMWV4ZmRpNGt6ZUNiZU9vMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVS9DMkVzSWsxSVlYVm4xWkpvbVVFClorQitHU3d3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnSVlpdHZrMkQyQ0dSWkoybmJHZlhnL1AvVkcyVnNhNmsKT1crNVpGZ1VuTDhDSUVKZFphWWg3M3I3bnN6aGp4Nmk4NXlzVFEydUxHMkdUWllHOHlQanJlaXYKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
|
||||||
server: https://100.102.235.20:6443
|
|
||||||
name: default
|
|
||||||
contexts:
|
|
||||||
- context:
|
|
||||||
cluster: default
|
|
||||||
user: default
|
|
||||||
name: default
|
|
||||||
current-context: default
|
|
||||||
kind: Config
|
|
||||||
preferences: {}
|
|
||||||
users:
|
|
||||||
- name: default
|
|
||||||
user:
|
|
||||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrVENDQVRlZ0F3SUJBZ0lJZko4aDRBSlc4MXN3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOelU0TXpnME1EWXhNQjRYRFRJMU1Ea3lNREUyTURFd01Wb1hEVEkyTURreQpNREUyTURFd01Wb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJEZjRwOE1BQ1JGaS9jTnUKa3QxRFoyb0tjVDlMeEM0aGtPeWZBdlJqUVRhQUFBN2Z6L3ZYdFJTd2dkN0JpMjlHMEF2WlViQ201anNoUGRRZwpEdVdMRksyalNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCVEt2Y3FLMnZyQmM4b1pzay80SkhRWUdSN2ZKVEFLQmdncWhrak9QUVFEQWdOSUFEQkYKQWlCZ2M0WDZqSmhBNzRpZ1VTZFNBanc0Yks1d29SVUFXLzFwMkNwaThvbXJnQUloQUxBQ2tBdWU3dmo2aFc0ZwpqNUhZL2VhMWN0RjVjUERycjB4NllsYWpXWDJFCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkakNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTlRnek9EUXdOakV3SGhjTk1qVXdPVEl3TVRZd01UQXhXaGNOTXpVd09URTRNVFl3TVRBeApXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTlRnek9EUXdOakV3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFScjR0a1IzZGUzOEhnTUxlNjBRYURyUjA2SmdCRHNRNng5cXp0dVVpNU8KSVpkekVwVWdCMHB6aUw1YkJ3eFVkVDVHTk5yUEt0OWlNVy9PMi9FQWgxc1pvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXlyM0tpdHI2d1hQS0diSlArQ1IwCkdCa2UzeVV3Q2dZSUtvWkl6ajBFQXdJRFJ3QXdSQUlnRmMrVVhselRMUWluRzM0bHlzeGdSK2JOTFhFS1RaS2gKbTBpV0dkZUhPRGNDSUNGdXZDdWxLWEx1TjFLNjkrT0dHNnhoUnNyRzAyUmY3TDJsVlZsekp4dDcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
|
||||||
client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU5tTDRiZW5hQllDb3FZSGUwU2dWbzVaQ2hrQnNaQVZGOHYwQU5VeE9jOUpvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFTi9pbnd3QUpFV0w5dzI2UzNVTm5hZ3B4UDB2RUxpR1E3SjhDOUdOQk5vQUFEdC9QKzllMQpGTENCM3NHTGIwYlFDOWxSc0tibU95RTkxQ0FPNVlzVXJRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
apiVersion: v1
|
|
||||||
clusters:
|
|
||||||
- cluster:
|
|
||||||
insecure-skip-tls-verify: true
|
|
||||||
server: https://100.102.235.20:6443
|
|
||||||
name: default
|
|
||||||
contexts:
|
|
||||||
- context:
|
|
||||||
cluster: default
|
|
||||||
user: default
|
|
||||||
name: default
|
|
||||||
current-context: default
|
|
||||||
kind: Config
|
|
||||||
preferences: {}
|
|
||||||
users:
|
|
||||||
- name: default
|
|
||||||
user:
|
|
||||||
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrRENDQVRlZ0F3SUJBZ0lJWHliZTEvMDh1N2N3Q2dZSUtvWkl6ajBFQXdJd0l6RWhNQjhHQTFVRUF3d1kKYXpOekxXTnNhV1Z1ZEMxallVQXhOelUzTURnMU9EUTRNQjRYRFRJMU1Ea3dOVEUxTWpRd09Gb1hEVEkyTURrdwpOVEUxTWpRd09Gb3dNREVYTUJVR0ExVUVDaE1PYzNsemRHVnRPbTFoYzNSbGNuTXhGVEFUQmdOVkJBTVRESE41CmMzUmxiVHBoWkcxcGJqQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJOWEs5VndoYWNaT1BjNVQKVGp2bVdCdDJaZmxiWmkzM1pjZk5VWVRTSGUxbzZaMEhvUVhHdDN5V2lrOVdmUGF6OTRYSHZVZXdLSmpOTnJBWgpsYzk2U21HalNEQkdNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFmCkJnTlZIU01FR0RBV2dCVE5CbDhSUGJnRTBFVXRUeGJyUXhyekE0Lzg2VEFLQmdncWhrak9QUVFEQWdOSEFEQkUKQWlBcmUySmNPa0lDbmhZWXptODZCVThEampNdFJZUTE1SWRoamJuenZPZ09WUUlnREtsaHIxL1FKWkMwellaLwoveUt5OEEzTWN4aXRQMEJkdXBvQzhnRDdrQkU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdFkyeHAKWlc1MExXTmhRREUzTlRjd09EVTRORGd3SGhjTk1qVXdPVEExTVRVeU5EQTRXaGNOTXpVd09UQXpNVFV5TkRBNApXakFqTVNFd0h3WURWUVFEREJock0zTXRZMnhwWlc1MExXTmhRREUzTlRjd09EVTRORGd3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFUNlZCdUI4UStFblNXOUFZT0N3b0ZsUFcwdzdqUjZlZC9qdTArbVIySDgKVkdnTk1qdXFUalU0a3o0RWhrYmJsaHloVVc5ZE9FWVRJSDM2bVlGUHltaVBvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXpRWmZFVDI0Qk5CRkxVOFc2ME1hCjh3T1AvT2t3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQVBja200cHA2anI1aStWcFRLbDNFTU5EWmNoQTZ5eXgKVDA4UCt5eHlieGxyQWlCZWJ6cDFqSDBYbUZKVjcxWjd2dDZFMzlsVTcyTTJJdlM0YW1zUncvd1lqdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
|
|
||||||
client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUFPNjA5Q2tBNEl1NXQyRFdMVkhBMHRDTFBZSHlBZ21nQlBrU3V2OElXOUVvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFMWNyMVhDRnB4azQ5emxOT08rWllHM1psK1Z0bUxmZGx4ODFSaE5JZDdXanBuUWVoQmNhMwpmSmFLVDFaODlyUDNoY2U5UjdBb21NMDJzQm1WejNwS1lRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
---
|
|
||||||
- name: List available LXC templates
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: List templates in local storage
|
|
||||||
command: pveam list local
|
|
||||||
register: templates
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Show Debian templates
|
|
||||||
debug:
|
|
||||||
msg: "{{ templates.stdout_lines | select('search', 'debian') | list }}"
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
MariaDB Container Credentials
|
|
||||||
=============================
|
|
||||||
Created: 2025-09-12
|
|
||||||
|
|
||||||
Container Details:
|
|
||||||
- Container ID: 301
|
|
||||||
- Host: lab02
|
|
||||||
- IP Address: 10.0.19.6
|
|
||||||
- Port: 3306
|
|
||||||
|
|
||||||
Root Credentials:
|
|
||||||
- Username: root
|
|
||||||
- Password: dOtPgrVnkIW1zwfjvW9rSw
|
|
||||||
- Connection: mysql -h 10.0.19.6 -u root -p'dOtPgrVnkIW1zwfjvW9rSw'
|
|
||||||
|
|
||||||
Wavelog Database:
|
|
||||||
- Database: wavelog
|
|
||||||
- Username: wavelog
|
|
||||||
- Password: m4icNmGTRtOMgrNxsxEdrw
|
|
||||||
- Connection: mysql -h 10.0.19.6 -u wavelog -p'm4icNmGTRtOMgrNxsxEdrw' wavelog
|
|
||||||
|
|
||||||
Kubernetes Secret:
|
|
||||||
kubectl create secret generic wavelog-db-secret --from-literal=password="m4icNmGTRtOMgrNxsxEdrw" -n wavelog
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
---
|
|
||||||
- name: Migrate template to all Proxmox nodes
|
|
||||||
hosts: lab02
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
template_vmid: 9000
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Migrate template to lab03
|
|
||||||
command: qm migrate {{ template_vmid }} lab03
|
|
||||||
register: migrate_lab03
|
|
||||||
failed_when:
|
|
||||||
- migrate_lab03.rc != 0
|
|
||||||
- "'already on node' not in migrate_lab03.stderr"
|
|
||||||
|
|
||||||
- name: Migrate template to lab04
|
|
||||||
command: qm migrate {{ template_vmid }} lab04
|
|
||||||
register: migrate_lab04
|
|
||||||
failed_when:
|
|
||||||
- migrate_lab04.rc != 0
|
|
||||||
- "'already on node' not in migrate_lab04.stderr"
|
|
||||||
|
|
||||||
- name: Migrate template back to lab02
|
|
||||||
command: qm migrate {{ template_vmid }} lab02
|
|
||||||
register: migrate_back
|
|
||||||
failed_when:
|
|
||||||
- migrate_back.rc != 0
|
|
||||||
- "'already on node' not in migrate_back.stderr"
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
---
|
|
||||||
- name: Configure Ceph RBD access on K3s nodes
|
|
||||||
hosts: k3s_cluster
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ceph_monitors: "10.0.16.231:6789,10.0.16.232:6789,10.0.16.233:6789"
|
|
||||||
ceph_user: "kubernetes"
|
|
||||||
ceph_key: "AQAq14Jo/g4ZORAAwxpPOmqj1PYgmih6s6b4vA=="
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create Ceph configuration file
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
[global]
|
|
||||||
fsid = 6e5e8932-3613-471d-afa0-410fade4d4ff
|
|
||||||
mon_host = 10.0.16.231,10.0.16.232,10.0.16.233
|
|
||||||
auth_cluster_required = cephx
|
|
||||||
auth_service_required = cephx
|
|
||||||
auth_client_required = cephx
|
|
||||||
dest: /etc/ceph/ceph.conf
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Create Ceph keyring for kubernetes user
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
[client.kubernetes]
|
|
||||||
key = {{ ceph_key }}
|
|
||||||
dest: /etc/ceph/ceph.client.kubernetes.keyring
|
|
||||||
mode: '0600'
|
|
||||||
|
|
||||||
- name: Test Ceph connectivity
|
|
||||||
shell: |
|
|
||||||
rbd ls kubernetes --id kubernetes
|
|
||||||
register: rbd_test
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Show RBD test result
|
|
||||||
debug:
|
|
||||||
var: rbd_test
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
---
|
|
||||||
- name: Pre-upgrade checks for PostgreSQL via Proxmox
|
|
||||||
hosts: lab02 # Proxmox host
|
|
||||||
become: yes
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
container_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if container is running
|
|
||||||
command: pct status {{ container_id }}
|
|
||||||
register: container_status
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display container status
|
|
||||||
debug:
|
|
||||||
var: container_status.stdout
|
|
||||||
|
|
||||||
- name: Check current PostgreSQL version
|
|
||||||
command: pct exec {{ container_id }} -- sudo -u postgres psql -t -c "SELECT version();"
|
|
||||||
register: pg_version
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current version
|
|
||||||
debug:
|
|
||||||
msg: "Current version: {{ pg_version.stdout }}"
|
|
||||||
|
|
||||||
- name: List PostgreSQL clusters
|
|
||||||
command: pct exec {{ container_id }} -- pg_lsclusters
|
|
||||||
register: pg_clusters
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display clusters
|
|
||||||
debug:
|
|
||||||
var: pg_clusters.stdout_lines
|
|
||||||
|
|
||||||
- name: Check disk space in container
|
|
||||||
command: pct exec {{ container_id }} -- df -h /var/lib/postgresql
|
|
||||||
register: disk_space
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display disk space
|
|
||||||
debug:
|
|
||||||
var: disk_space.stdout_lines
|
|
||||||
|
|
||||||
- name: List installed PostgreSQL packages
|
|
||||||
command: pct exec {{ container_id }} -- dpkg -l | grep postgresql
|
|
||||||
register: pg_packages
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display PostgreSQL packages
|
|
||||||
debug:
|
|
||||||
var: pg_packages.stdout_lines
|
|
||||||
|
|
||||||
- name: Get database sizes
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- sudo -u postgres psql -t -c "SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) FROM pg_database WHERE datname NOT IN ('template0', 'template1') ORDER BY pg_database_size(pg_database.datname) DESC;"
|
|
||||||
register: db_sizes
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display database sizes
|
|
||||||
debug:
|
|
||||||
var: db_sizes.stdout_lines
|
|
||||||
|
|
||||||
- name: Check active connections
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- sudo -u postgres psql -t -c "SELECT count(*) as connections, datname FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;"
|
|
||||||
register: active_connections
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display active connections
|
|
||||||
debug:
|
|
||||||
var: active_connections.stdout_lines
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
---
|
|
||||||
- name: Pre-upgrade checks for PostgreSQL
|
|
||||||
hosts: postgresql
|
|
||||||
become: yes
|
|
||||||
gather_facts: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check current PostgreSQL version
|
|
||||||
command: sudo -u postgres psql -t -c "SELECT version();"
|
|
||||||
register: pg_version
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current version
|
|
||||||
debug:
|
|
||||||
msg: "Current version: {{ pg_version.stdout }}"
|
|
||||||
|
|
||||||
- name: Check PostgreSQL service status
|
|
||||||
command: systemctl status postgresql
|
|
||||||
register: pg_status
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: List PostgreSQL clusters
|
|
||||||
command: pg_lsclusters
|
|
||||||
register: pg_clusters
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display clusters
|
|
||||||
debug:
|
|
||||||
var: pg_clusters.stdout_lines
|
|
||||||
|
|
||||||
- name: Get database sizes
|
|
||||||
become_user: postgres
|
|
||||||
shell: |
|
|
||||||
psql -t -c "SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) FROM pg_database WHERE datname NOT IN ('template0', 'template1') ORDER BY pg_database_size(pg_database.datname) DESC;"
|
|
||||||
register: db_sizes
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display database sizes
|
|
||||||
debug:
|
|
||||||
msg: "Database sizes:"
|
|
||||||
|
|
||||||
- name: Show database sizes
|
|
||||||
debug:
|
|
||||||
var: db_sizes.stdout_lines
|
|
||||||
|
|
||||||
- name: Check disk space
|
|
||||||
command: df -h /var/lib/postgresql
|
|
||||||
register: disk_space
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display disk space
|
|
||||||
debug:
|
|
||||||
var: disk_space.stdout_lines
|
|
||||||
|
|
||||||
- name: List installed PostgreSQL packages
|
|
||||||
shell: dpkg -l | grep postgresql | grep -E "^ii"
|
|
||||||
register: pg_packages
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display PostgreSQL packages
|
|
||||||
debug:
|
|
||||||
var: pg_packages.stdout_lines
|
|
||||||
|
|
||||||
- name: Check active connections
|
|
||||||
become_user: postgres
|
|
||||||
shell: |
|
|
||||||
psql -t -c "SELECT count(*) as connections, datname FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;"
|
|
||||||
register: active_connections
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display active connections
|
|
||||||
debug:
|
|
||||||
var: active_connections.stdout_lines
|
|
||||||
|
|
||||||
- name: Check for replication slots (if any)
|
|
||||||
become_user: postgres
|
|
||||||
command: psql -t -c "SELECT * FROM pg_replication_slots;"
|
|
||||||
register: replication_slots
|
|
||||||
changed_when: false
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display replication slots
|
|
||||||
debug:
|
|
||||||
var: replication_slots.stdout_lines
|
|
||||||
when: replication_slots.rc == 0
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
---
|
|
||||||
- name: Upgrade PostgreSQL from 15 to 17
|
|
||||||
hosts: postgresql
|
|
||||||
become: yes
|
|
||||||
gather_facts: yes
|
|
||||||
vars:
|
|
||||||
old_version: 15
|
|
||||||
new_version: 17
|
|
||||||
postgres_data_dir: "/var/lib/postgresql"
|
|
||||||
backup_dir: "/var/backups/postgresql-upgrade-{{ ansible_date_time.epoch }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check current PostgreSQL version
|
|
||||||
command: sudo -u postgres psql -t -c "SELECT version();"
|
|
||||||
register: pg_version_check
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current PostgreSQL version
|
|
||||||
debug:
|
|
||||||
msg: "Current PostgreSQL version: {{ pg_version_check.stdout }}"
|
|
||||||
|
|
||||||
- name: Install required packages
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- postgresql-{{ new_version }}
|
|
||||||
- postgresql-client-{{ new_version }}
|
|
||||||
- postgresql-contrib-{{ new_version }}
|
|
||||||
- postgresql-{{ new_version }}-postgis-3 # If PostGIS is needed
|
|
||||||
state: present
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Stop PostgreSQL services
|
|
||||||
service:
|
|
||||||
name: "{{ item }}"
|
|
||||||
state: stopped
|
|
||||||
loop:
|
|
||||||
- "postgresql@{{ old_version }}-main"
|
|
||||||
- "postgresql@{{ new_version }}-main"
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Create backup directory
|
|
||||||
file:
|
|
||||||
path: "{{ backup_dir }}"
|
|
||||||
state: directory
|
|
||||||
owner: postgres
|
|
||||||
group: postgres
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Get list of databases
|
|
||||||
become_user: postgres
|
|
||||||
postgresql_info:
|
|
||||||
filter: databases
|
|
||||||
register: pg_databases
|
|
||||||
|
|
||||||
- name: Backup all databases
|
|
||||||
become_user: postgres
|
|
||||||
command: |
|
|
||||||
pg_dumpall -p 5432 > {{ backup_dir }}/all_databases.sql
|
|
||||||
environment:
|
|
||||||
PGVERSION: "{{ old_version }}"
|
|
||||||
|
|
||||||
- name: Backup PostgreSQL configuration files
|
|
||||||
copy:
|
|
||||||
src: "{{ item }}"
|
|
||||||
dest: "{{ backup_dir }}/"
|
|
||||||
remote_src: yes
|
|
||||||
owner: postgres
|
|
||||||
group: postgres
|
|
||||||
loop:
|
|
||||||
- "/etc/postgresql/{{ old_version }}/main/postgresql.conf"
|
|
||||||
- "/etc/postgresql/{{ old_version }}/main/pg_hba.conf"
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Check if new cluster exists
|
|
||||||
stat:
|
|
||||||
path: "/etc/postgresql/{{ new_version }}/main"
|
|
||||||
register: new_cluster_check
|
|
||||||
|
|
||||||
- name: Drop new cluster if it exists
|
|
||||||
command: pg_dropcluster {{ new_version }} main --stop
|
|
||||||
when: new_cluster_check.stat.exists
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Upgrade PostgreSQL cluster
|
|
||||||
command: |
|
|
||||||
pg_upgradecluster {{ old_version }} main
|
|
||||||
register: upgrade_result
|
|
||||||
environment:
|
|
||||||
LC_ALL: C.UTF-8
|
|
||||||
LANG: C.UTF-8
|
|
||||||
|
|
||||||
- name: Show upgrade result
|
|
||||||
debug:
|
|
||||||
var: upgrade_result.stdout_lines
|
|
||||||
|
|
||||||
- name: Start new PostgreSQL service
|
|
||||||
service:
|
|
||||||
name: "postgresql@{{ new_version }}-main"
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
|
|
||||||
- name: Verify new PostgreSQL version
|
|
||||||
command: sudo -u postgres psql -p 5432 -t -c "SELECT version();"
|
|
||||||
register: new_pg_version
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display new PostgreSQL version
|
|
||||||
debug:
|
|
||||||
msg: "New PostgreSQL version: {{ new_pg_version.stdout }}"
|
|
||||||
|
|
||||||
- name: Update PostgreSQL configuration
|
|
||||||
lineinfile:
|
|
||||||
path: "/etc/postgresql/{{ new_version }}/main/postgresql.conf"
|
|
||||||
regexp: "{{ item.regexp }}"
|
|
||||||
line: "{{ item.line }}"
|
|
||||||
loop:
|
|
||||||
- { regexp: '^#?listen_addresses', line: "listen_addresses = '*'" }
|
|
||||||
- { regexp: '^#?max_connections', line: "max_connections = 200" }
|
|
||||||
- { regexp: '^#?shared_buffers', line: "shared_buffers = 2GB" }
|
|
||||||
- { regexp: '^#?effective_cache_size', line: "effective_cache_size = 6GB" }
|
|
||||||
- { regexp: '^#?work_mem', line: "work_mem = 16MB" }
|
|
||||||
notify: restart postgresql
|
|
||||||
|
|
||||||
- name: Update pg_hba.conf for network access
|
|
||||||
blockinfile:
|
|
||||||
path: "/etc/postgresql/{{ new_version }}/main/pg_hba.conf"
|
|
||||||
block: |
|
|
||||||
# Allow connections from K3s cluster
|
|
||||||
host all all 10.0.19.0/24 scram-sha-256
|
|
||||||
host all all 10.0.0.0/8 scram-sha-256
|
|
||||||
marker: "# {mark} ANSIBLE MANAGED BLOCK - K3s access"
|
|
||||||
notify: restart postgresql
|
|
||||||
|
|
||||||
- name: Check if PostGIS extension needs update
|
|
||||||
become_user: postgres
|
|
||||||
command: psql -d forgejo -c "SELECT PostGIS_version();"
|
|
||||||
register: postgis_check
|
|
||||||
ignore_errors: yes
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Update PostGIS extension if present
|
|
||||||
become_user: postgres
|
|
||||||
command: psql -d {{ item }} -c "ALTER EXTENSION postgis UPDATE;"
|
|
||||||
loop:
|
|
||||||
- forgejo
|
|
||||||
- postgres
|
|
||||||
when: postgis_check.rc == 0
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Run ANALYZE on all databases
|
|
||||||
become_user: postgres
|
|
||||||
command: psql -d {{ item }} -c "ANALYZE;"
|
|
||||||
loop: "{{ pg_databases.databases.keys() | select('ne', 'template0') | list }}"
|
|
||||||
when: pg_databases.databases is defined
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display upgrade summary
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "PostgreSQL upgrade completed successfully!"
|
|
||||||
- "Old version: PostgreSQL {{ old_version }}"
|
|
||||||
- "New version: PostgreSQL {{ new_version }}"
|
|
||||||
- "Backup location: {{ backup_dir }}"
|
|
||||||
- ""
|
|
||||||
- "IMPORTANT: The old cluster is still present but stopped."
|
|
||||||
- "After verifying everything works correctly, you can remove it with:"
|
|
||||||
- " sudo pg_dropcluster {{ old_version }} main"
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart postgresql
|
|
||||||
service:
|
|
||||||
name: "postgresql@{{ new_version }}-main"
|
|
||||||
state: restarted
|
|
||||||
|
|
@ -1,184 +0,0 @@
|
||||||
# Manual PostgreSQL 15 to 17 Upgrade Steps
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
- SSH into Proxmox host: `ssh root@10.0.16.231` (or appropriate host)
|
|
||||||
- Access PostgreSQL container: `pct enter 300`
|
|
||||||
|
|
||||||
## Step 1: Pre-upgrade Checks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check current version
|
|
||||||
sudo -u postgres psql -t -c "SELECT version();"
|
|
||||||
|
|
||||||
# List current clusters
|
|
||||||
pg_lsclusters
|
|
||||||
|
|
||||||
# Check disk space
|
|
||||||
df -h /var/lib/postgresql
|
|
||||||
|
|
||||||
# List databases and sizes
|
|
||||||
sudo -u postgres psql -t -c "SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) FROM pg_database WHERE datname NOT IN ('template0', 'template1') ORDER BY pg_database_size(pg_database.datname) DESC;"
|
|
||||||
|
|
||||||
# Check active connections
|
|
||||||
sudo -u postgres psql -t -c "SELECT count(*) as connections, datname FROM pg_stat_activity GROUP BY datname ORDER BY connections DESC;"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 2: Backup Current Data
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create backup directory
|
|
||||||
mkdir -p /var/backups/postgresql-upgrade-$(date +%s)
|
|
||||||
cd /var/backups/postgresql-upgrade-$(date +%s)
|
|
||||||
|
|
||||||
# Backup all databases
|
|
||||||
sudo -u postgres pg_dumpall > all_databases.sql
|
|
||||||
|
|
||||||
# Backup configuration files
|
|
||||||
cp /etc/postgresql/15/main/postgresql.conf postgresql.conf.backup
|
|
||||||
cp /etc/postgresql/15/main/pg_hba.conf pg_hba.conf.backup
|
|
||||||
|
|
||||||
# Note important settings from postgresql.conf
|
|
||||||
grep -E "listen_addresses|max_connections|shared_buffers|effective_cache_size|work_mem" /etc/postgresql/15/main/postgresql.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 3: Install PostgreSQL 17
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add PostgreSQL APT repository
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y wget ca-certificates
|
|
||||||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
|
|
||||||
echo "deb http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
|
||||||
apt-get update
|
|
||||||
|
|
||||||
# Install PostgreSQL 17
|
|
||||||
apt-get install -y postgresql-17 postgresql-client-17 postgresql-contrib-17
|
|
||||||
|
|
||||||
# If using PostGIS
|
|
||||||
apt-get install -y postgresql-17-postgis-3
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 4: Stop Services
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Stop all PostgreSQL services
|
|
||||||
systemctl stop postgresql
|
|
||||||
|
|
||||||
# Verify services are stopped
|
|
||||||
systemctl status postgresql
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 5: Perform the Upgrade
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check clusters again
|
|
||||||
pg_lsclusters
|
|
||||||
|
|
||||||
# Drop the empty PostgreSQL 17 cluster (if it was auto-created)
|
|
||||||
pg_dropcluster 17 main --stop
|
|
||||||
|
|
||||||
# Upgrade the cluster
|
|
||||||
pg_upgradecluster 15 main
|
|
||||||
|
|
||||||
# This will:
|
|
||||||
# - Create new cluster with PostgreSQL 17
|
|
||||||
# - Migrate all data
|
|
||||||
# - Update ports (old cluster moves to 5433, new stays on 5432)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 6: Configure PostgreSQL 17
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Edit postgresql.conf
|
|
||||||
nano /etc/postgresql/17/main/postgresql.conf
|
|
||||||
|
|
||||||
# Update these settings:
|
|
||||||
# listen_addresses = '*'
|
|
||||||
# max_connections = 200
|
|
||||||
# shared_buffers = 2GB
|
|
||||||
# effective_cache_size = 6GB
|
|
||||||
# work_mem = 16MB
|
|
||||||
|
|
||||||
# Edit pg_hba.conf for network access
|
|
||||||
nano /etc/postgresql/17/main/pg_hba.conf
|
|
||||||
|
|
||||||
# Add these lines:
|
|
||||||
# host all all 10.0.19.0/24 scram-sha-256
|
|
||||||
# host all all 10.0.0.0/8 scram-sha-256
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 7: Start and Verify
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start PostgreSQL 17
|
|
||||||
systemctl start postgresql@17-main
|
|
||||||
systemctl enable postgresql@17-main
|
|
||||||
|
|
||||||
# Check status
|
|
||||||
systemctl status postgresql@17-main
|
|
||||||
|
|
||||||
# Verify version
|
|
||||||
sudo -u postgres psql -p 5432 -t -c "SELECT version();"
|
|
||||||
|
|
||||||
# Check clusters
|
|
||||||
pg_lsclusters
|
|
||||||
|
|
||||||
# Test connection
|
|
||||||
sudo -u postgres psql -l
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 8: Post-upgrade Tasks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Update PostGIS extension (if used)
|
|
||||||
sudo -u postgres psql -d forgejo -c "ALTER EXTENSION postgis UPDATE;"
|
|
||||||
|
|
||||||
# Run ANALYZE on all databases for optimizer statistics
|
|
||||||
for db in $(sudo -u postgres psql -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1');"); do
|
|
||||||
echo "Analyzing $db..."
|
|
||||||
sudo -u postgres psql -d $db -c 'ANALYZE;'
|
|
||||||
done
|
|
||||||
|
|
||||||
# Test remote connectivity
|
|
||||||
# From another host:
|
|
||||||
# psql -h 10.0.19.5 -U forgejo -d forgejo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Step 9: Cleanup (After Verification)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Once everything is confirmed working:
|
|
||||||
|
|
||||||
# Stop old cluster
|
|
||||||
systemctl stop postgresql@15-main
|
|
||||||
|
|
||||||
# Optional: Remove old cluster (only after thorough testing!)
|
|
||||||
# pg_dropcluster 15 main
|
|
||||||
|
|
||||||
# Remove old packages (only after thorough testing!)
|
|
||||||
# apt-get remove postgresql-15 postgresql-client-15 postgresql-contrib-15
|
|
||||||
```
|
|
||||||
|
|
||||||
## Important Notes
|
|
||||||
|
|
||||||
- The old PostgreSQL 15 cluster will remain on port 5433
|
|
||||||
- The new PostgreSQL 17 cluster will be on port 5432
|
|
||||||
- Ensure all applications are tested before removing the old cluster
|
|
||||||
- Keep backups for at least 30 days after upgrade
|
|
||||||
- Monitor logs: `tail -f /var/log/postgresql/postgresql-17-main.log`
|
|
||||||
|
|
||||||
## Rollback Plan
|
|
||||||
|
|
||||||
If issues occur:
|
|
||||||
```bash
|
|
||||||
# Stop PostgreSQL 17
|
|
||||||
systemctl stop postgresql@17-main
|
|
||||||
|
|
||||||
# Change PostgreSQL 15 back to port 5432
|
|
||||||
sed -i 's/port = 5433/port = 5432/' /etc/postgresql/15/main/postgresql.conf
|
|
||||||
|
|
||||||
# Start PostgreSQL 15
|
|
||||||
systemctl start postgresql@15-main
|
|
||||||
|
|
||||||
# Update applications to point back to PostgreSQL 15
|
|
||||||
```
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
---
|
|
||||||
- name: Upgrade PostgreSQL from 15 to 17 via Proxmox
|
|
||||||
hosts: lab02 # Proxmox host where the LXC container runs
|
|
||||||
become: yes
|
|
||||||
gather_facts: yes
|
|
||||||
vars:
|
|
||||||
container_id: 300
|
|
||||||
old_version: 15
|
|
||||||
new_version: 17
|
|
||||||
backup_dir: "/var/backups/postgresql-upgrade-{{ ansible_date_time.epoch }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check current PostgreSQL version
|
|
||||||
command: pct exec {{ container_id }} -- sudo -u postgres psql -t -c "SELECT version();"
|
|
||||||
register: pg_version_check
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current PostgreSQL version
|
|
||||||
debug:
|
|
||||||
msg: "Current PostgreSQL version: {{ pg_version_check.stdout }}"
|
|
||||||
|
|
||||||
- name: Update package lists in container
|
|
||||||
command: pct exec {{ container_id }} -- apt-get update
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 17 repository
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
apt-get install -y wget ca-certificates &&
|
|
||||||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - &&
|
|
||||||
echo 'deb http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list &&
|
|
||||||
apt-get update
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 17 packages
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- apt-get install -y postgresql-17 postgresql-client-17 postgresql-contrib-17 postgresql-17-postgis-3
|
|
||||||
|
|
||||||
- name: Stop PostgreSQL services
|
|
||||||
command: pct exec {{ container_id }} -- systemctl stop postgresql
|
|
||||||
|
|
||||||
- name: Create backup directory
|
|
||||||
command: pct exec {{ container_id }} -- mkdir -p {{ backup_dir }}
|
|
||||||
|
|
||||||
- name: Set ownership of backup directory
|
|
||||||
command: pct exec {{ container_id }} -- chown postgres:postgres {{ backup_dir }}
|
|
||||||
|
|
||||||
- name: Backup all databases
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- sudo -u postgres pg_dumpall -p 5432 > {{ container_id }}_postgres_backup.sql
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Copy backup into container
|
|
||||||
command: |
|
|
||||||
pct push {{ container_id }} {{ container_id }}_postgres_backup.sql {{ backup_dir }}/all_databases.sql
|
|
||||||
|
|
||||||
- name: List current clusters
|
|
||||||
command: pct exec {{ container_id }} -- pg_lsclusters
|
|
||||||
register: clusters_before
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display current clusters
|
|
||||||
debug:
|
|
||||||
var: clusters_before.stdout_lines
|
|
||||||
|
|
||||||
- name: Drop PostgreSQL 17 cluster if exists
|
|
||||||
command: pct exec {{ container_id }} -- pg_dropcluster {{ new_version }} main --stop
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Upgrade PostgreSQL cluster
|
|
||||||
command: pct exec {{ container_id }} -- pg_upgradecluster {{ old_version }} main
|
|
||||||
register: upgrade_result
|
|
||||||
|
|
||||||
- name: Show upgrade result
|
|
||||||
debug:
|
|
||||||
var: upgrade_result.stdout_lines
|
|
||||||
|
|
||||||
- name: Start PostgreSQL 17
|
|
||||||
command: pct exec {{ container_id }} -- systemctl start postgresql@{{ new_version }}-main
|
|
||||||
|
|
||||||
- name: Enable PostgreSQL 17
|
|
||||||
command: pct exec {{ container_id }} -- systemctl enable postgresql@{{ new_version }}-main
|
|
||||||
|
|
||||||
- name: Verify new PostgreSQL version
|
|
||||||
command: pct exec {{ container_id }} -- sudo -u postgres psql -p 5432 -t -c "SELECT version();"
|
|
||||||
register: new_pg_version
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display new PostgreSQL version
|
|
||||||
debug:
|
|
||||||
msg: "New PostgreSQL version: {{ new_pg_version.stdout }}"
|
|
||||||
|
|
||||||
- name: Update PostgreSQL configuration for network access
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
sed -i \"s/^#listen_addresses.*/listen_addresses = '*'/\" /etc/postgresql/{{ new_version }}/main/postgresql.conf &&
|
|
||||||
echo 'host all all 10.0.19.0/24 scram-sha-256' >> /etc/postgresql/{{ new_version }}/main/pg_hba.conf &&
|
|
||||||
echo 'host all all 10.0.0.0/8 scram-sha-256' >> /etc/postgresql/{{ new_version }}/main/pg_hba.conf
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Restart PostgreSQL to apply configuration
|
|
||||||
command: pct exec {{ container_id }} -- systemctl restart postgresql@{{ new_version }}-main
|
|
||||||
|
|
||||||
- name: Run ANALYZE on all databases
|
|
||||||
command: |
|
|
||||||
pct exec {{ container_id }} -- bash -c "
|
|
||||||
for db in \$(sudo -u postgres psql -t -c \"SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1');\"); do
|
|
||||||
sudo -u postgres psql -d \$db -c 'ANALYZE;'
|
|
||||||
done
|
|
||||||
"
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Clean up local backup file
|
|
||||||
file:
|
|
||||||
path: "{{ container_id }}_postgres_backup.sql"
|
|
||||||
state: absent
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Display upgrade summary
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "PostgreSQL upgrade completed successfully!"
|
|
||||||
- "Old version: PostgreSQL {{ old_version }}"
|
|
||||||
- "New version: PostgreSQL {{ new_version }}"
|
|
||||||
- "Backup location in container: {{ backup_dir }}"
|
|
||||||
- ""
|
|
||||||
- "IMPORTANT: The old cluster is still present but stopped."
|
|
||||||
- "After verifying everything works correctly, you can remove it with:"
|
|
||||||
- " pct exec {{ container_id }} -- pg_dropcluster {{ old_version }} main"
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
---
|
|
||||||
- name: Recreate K3s Worker-2 VM on Proxmox
|
|
||||||
hosts: lab02
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
template_vmid: 9000
|
|
||||||
network_gateway: "10.0.19.254"
|
|
||||||
ssh_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHLyVSEEAEbGZZqwPwEup0XrlTpu3x3iF9ExvvQPA4xN graham@mcintire.me"
|
|
||||||
|
|
||||||
worker2:
|
|
||||||
vmid: 1201
|
|
||||||
name: "home-k3s-worker-2"
|
|
||||||
ip: "10.0.19.111/24"
|
|
||||||
cores: 4
|
|
||||||
memory: 8192
|
|
||||||
disk: "64G"
|
|
||||||
target_node: "lab03"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Clone template to create worker-2
|
|
||||||
command: |
|
|
||||||
qm clone {{ template_vmid }} {{ worker2.vmid }} \
|
|
||||||
--name {{ worker2.name }} \
|
|
||||||
--full true \
|
|
||||||
--target {{ worker2.target_node }}
|
|
||||||
register: clone_result
|
|
||||||
|
|
||||||
- name: Configure worker-2 VM
|
|
||||||
delegate_to: lab03
|
|
||||||
command: |
|
|
||||||
qm set {{ worker2.vmid }} \
|
|
||||||
--cores {{ worker2.cores }} \
|
|
||||||
--memory {{ worker2.memory }} \
|
|
||||||
--ipconfig0 ip={{ worker2.ip }},gw={{ network_gateway }} \
|
|
||||||
--sshkeys /root/.ssh/authorized_keys \
|
|
||||||
--onboot 1
|
|
||||||
|
|
||||||
- name: Resize disk if needed
|
|
||||||
delegate_to: lab03
|
|
||||||
command: |
|
|
||||||
qm resize {{ worker2.vmid }} scsi0 {{ worker2.disk }}
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Start worker-2 VM
|
|
||||||
delegate_to: lab03
|
|
||||||
command: qm start {{ worker2.vmid }}
|
|
||||||
|
|
||||||
- name: Wait for VM to boot
|
|
||||||
pause:
|
|
||||||
seconds: 90
|
|
||||||
|
|
||||||
- name: Test SSH connectivity
|
|
||||||
delegate_to: localhost
|
|
||||||
wait_for:
|
|
||||||
host: 10.0.19.111
|
|
||||||
port: 22
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
- name: Configure K3s on worker-2
|
|
||||||
hosts: home-k3s-worker-2
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Wait for SSH to be ready
|
|
||||||
wait_for_connection:
|
|
||||||
delay: 30
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
- name: Gather facts
|
|
||||||
setup:
|
|
||||||
|
|
||||||
- name: Install curl
|
|
||||||
package:
|
|
||||||
name: curl
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Download k3s binary
|
|
||||||
get_url:
|
|
||||||
url: https://github.com/k3s-io/k3s/releases/download/v1.28.5+k3s1/k3s
|
|
||||||
dest: /usr/local/bin/k3s
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Create k3s config directory
|
|
||||||
file:
|
|
||||||
path: /etc/rancher/k3s
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Get token from control node
|
|
||||||
delegate_to: home-k3s-control-1
|
|
||||||
slurp:
|
|
||||||
src: /var/lib/rancher/k3s/server/node-token
|
|
||||||
register: node_token
|
|
||||||
|
|
||||||
- name: Create k3s agent config
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
server: https://10.0.19.100:6443
|
|
||||||
token: {{ node_token.content | b64decode | trim }}
|
|
||||||
with-node-id: true
|
|
||||||
dest: /etc/rancher/k3s/config.yaml
|
|
||||||
|
|
||||||
- name: Create k3s-agent systemd service
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
[Unit]
|
|
||||||
Description=Lightweight Kubernetes
|
|
||||||
Documentation=https://k3s.io
|
|
||||||
Wants=network-online.target
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=notify
|
|
||||||
EnvironmentFile=-/etc/default/%N
|
|
||||||
EnvironmentFile=-/etc/sysconfig/%N
|
|
||||||
KillMode=process
|
|
||||||
Delegate=yes
|
|
||||||
LimitNOFILE=1048576
|
|
||||||
LimitNPROC=infinity
|
|
||||||
LimitCORE=infinity
|
|
||||||
TasksMax=infinity
|
|
||||||
TimeoutStartSec=0
|
|
||||||
Restart=always
|
|
||||||
RestartSec=5s
|
|
||||||
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
|
|
||||||
ExecStartPre=-/sbin/modprobe br_netfilter
|
|
||||||
ExecStartPre=-/sbin/modprobe overlay
|
|
||||||
ExecStart=/usr/local/bin/k3s agent
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
dest: /etc/systemd/system/k3s-agent.service
|
|
||||||
|
|
||||||
- name: Start k3s-agent service
|
|
||||||
systemd:
|
|
||||||
name: k3s-agent
|
|
||||||
daemon_reload: yes
|
|
||||||
enabled: yes
|
|
||||||
state: started
|
|
||||||
|
|
||||||
- name: Verify worker-2 joined cluster
|
|
||||||
hosts: home-k3s-control-1
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Wait for worker-2 to join
|
|
||||||
shell: /usr/local/bin/k3s kubectl get nodes | grep -E "home-k3s-worker-2.*Ready"
|
|
||||||
register: worker2_status
|
|
||||||
until: worker2_status.rc == 0
|
|
||||||
retries: 30
|
|
||||||
delay: 10
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Display cluster status
|
|
||||||
command: /usr/local/bin/k3s kubectl get nodes
|
|
||||||
register: final_status
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
|
|
||||||
|
|
||||||
- name: Show cluster status
|
|
||||||
debug:
|
|
||||||
var: final_status.stdout_lines
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
- name: Replicate Debian 13 template to all Proxmox nodes
|
|
||||||
hosts: proxmox
|
|
||||||
gather_facts: no
|
|
||||||
vars:
|
|
||||||
template_vmid: 9000
|
|
||||||
storage: "ceph"
|
|
||||||
source_node: "lab02"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if template exists on this node
|
|
||||||
command: qm status {{ template_vmid }}
|
|
||||||
register: vm_check
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Clone template from source node
|
|
||||||
when:
|
|
||||||
- vm_check.rc != 0
|
|
||||||
- inventory_hostname != source_node
|
|
||||||
command: |
|
|
||||||
qm clone {{ template_vmid }} {{ template_vmid }} --name debian-13-cloudinit --target {{ inventory_hostname }}
|
|
||||||
delegate_to: "{{ source_node }}"
|
|
||||||
|
|
||||||
- name: Template status
|
|
||||||
debug:
|
|
||||||
msg: "Template {{ template_vmid }} exists on {{ inventory_hostname }}"
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup APRS Database in PostgreSQL LXC
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create APRS database and user
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -c "CREATE USER aprs WITH PASSWORD 'xK9mP2vQ7sR3nL5w';"
|
|
||||||
ignore_errors: yes
|
|
||||||
register: create_user
|
|
||||||
|
|
||||||
- name: Create APRS database
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -c "CREATE DATABASE aprs OWNER aprs;"
|
|
||||||
ignore_errors: yes
|
|
||||||
register: create_db
|
|
||||||
|
|
||||||
- name: Grant privileges on APRS database
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "GRANT ALL PRIVILEGES ON DATABASE aprs TO aprs; GRANT ALL ON SCHEMA public TO aprs;"
|
|
||||||
|
|
||||||
- name: Test APRS database connection
|
|
||||||
command: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT current_database(), current_user;"
|
|
||||||
register: db_test
|
|
||||||
|
|
||||||
- name: Display results
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
APRS database setup completed!
|
|
||||||
|
|
||||||
User creation: {{ 'Created' if create_user.rc == 0 else 'Already exists or failed' }}
|
|
||||||
Database creation: {{ 'Created' if create_db.rc == 0 else 'Already exists or failed' }}
|
|
||||||
|
|
||||||
Connection details:
|
|
||||||
- Host: 10.0.19.5
|
|
||||||
- Port: 5432
|
|
||||||
- Database: aprs
|
|
||||||
- User: aprs
|
|
||||||
- Password: xK9mP2vQ7sR3nL5w
|
|
||||||
|
|
||||||
Connection test output:
|
|
||||||
{{ db_test.stdout }}
|
|
||||||
|
|
||||||
Connection strings:
|
|
||||||
- PostgreSQL: postgresql://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:5432/aprs
|
|
||||||
- Ecto: ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:5432/aprs
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
---
|
|
||||||
# This playbook sets up direct Ceph RBD access for Kubernetes
|
|
||||||
# It replaces NFS-based access with native Ceph RBD CSI
|
|
||||||
|
|
||||||
- name: Ensure Ceph kubernetes pool exists
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Check if kubernetes pool exists
|
|
||||||
command: ceph osd pool ls
|
|
||||||
register: ceph_pools
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Create kubernetes pool if not exists
|
|
||||||
command: ceph osd pool create kubernetes 128 128
|
|
||||||
when: "'kubernetes' not in ceph_pools.stdout"
|
|
||||||
|
|
||||||
- name: Initialize pool for RBD use
|
|
||||||
command: rbd pool init kubernetes
|
|
||||||
when: "'kubernetes' not in ceph_pools.stdout"
|
|
||||||
|
|
||||||
- name: Check if kubernetes user exists
|
|
||||||
command: ceph auth list
|
|
||||||
register: ceph_users
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Create kubernetes user if not exists
|
|
||||||
shell: |
|
|
||||||
ceph auth get-or-create client.kubernetes \
|
|
||||||
mon 'profile rbd' \
|
|
||||||
osd 'profile rbd pool=kubernetes' \
|
|
||||||
mgr 'profile rbd pool=kubernetes'
|
|
||||||
when: "'client.kubernetes' not in ceph_users.stdout"
|
|
||||||
|
|
||||||
- name: Get kubernetes user key
|
|
||||||
command: ceph auth print-key client.kubernetes
|
|
||||||
register: k8s_key
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display kubernetes key
|
|
||||||
debug:
|
|
||||||
msg: "Kubernetes key: {{ k8s_key.stdout }}"
|
|
||||||
|
|
||||||
- name: Set fact for kubernetes key
|
|
||||||
set_fact:
|
|
||||||
ceph_kubernetes_key: "{{ k8s_key.stdout }}"
|
|
||||||
|
|
||||||
- name: Setup Ceph client on K3s nodes
|
|
||||||
import_playbook: setup-ceph-clients-k3s.yml
|
|
||||||
|
|
||||||
- name: Deploy Ceph CSI
|
|
||||||
import_playbook: deploy-ceph-csi.yml
|
|
||||||
|
|
||||||
- name: Verify Ceph RBD setup
|
|
||||||
hosts: localhost
|
|
||||||
connection: local
|
|
||||||
vars:
|
|
||||||
kubeconfig: "{{ playbook_dir }}/kubeconfig"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check CSI driver status
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
echo "=== CSI Drivers ==="
|
|
||||||
kubectl get csidrivers
|
|
||||||
echo -e "\n=== CSI Nodes ==="
|
|
||||||
kubectl get csinodes
|
|
||||||
echo -e "\n=== Storage Classes ==="
|
|
||||||
kubectl get storageclass
|
|
||||||
echo -e "\n=== CSI Pods Status ==="
|
|
||||||
kubectl get pods -n ceph-csi
|
|
||||||
register: csi_status
|
|
||||||
|
|
||||||
- name: Display CSI status
|
|
||||||
debug:
|
|
||||||
var: csi_status.stdout_lines
|
|
||||||
|
|
||||||
- name: Create test application with Ceph RBD
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
cat <<EOF | kubectl apply -f -
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: ceph-test
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: test-rbd-pvc
|
|
||||||
namespace: ceph-test
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
storageClassName: ceph-rbd
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 5Gi
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: test-rbd-pod
|
|
||||||
namespace: ceph-test
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: test
|
|
||||||
image: nginx:alpine
|
|
||||||
volumeMounts:
|
|
||||||
- name: test-volume
|
|
||||||
mountPath: /data
|
|
||||||
volumes:
|
|
||||||
- name: test-volume
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: test-rbd-pvc
|
|
||||||
EOF
|
|
||||||
register: test_app
|
|
||||||
|
|
||||||
- name: Wait for test pod to be ready
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl wait --for=condition=ready pod -n ceph-test test-rbd-pod --timeout=120s
|
|
||||||
register: wait_result
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Check test application status
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
echo "=== Test PVC Status ==="
|
|
||||||
kubectl get pvc -n ceph-test
|
|
||||||
echo -e "\n=== Test Pod Status ==="
|
|
||||||
kubectl get pod -n ceph-test
|
|
||||||
echo -e "\n=== RBD Image List ==="
|
|
||||||
kubectl exec -n ceph-test test-rbd-pod -- df -h /data
|
|
||||||
register: test_status
|
|
||||||
when: wait_result is succeeded
|
|
||||||
|
|
||||||
- name: Display test results
|
|
||||||
debug:
|
|
||||||
var: test_status.stdout_lines
|
|
||||||
when: wait_result is succeeded
|
|
||||||
|
|
||||||
- name: Cleanup test resources
|
|
||||||
shell: |
|
|
||||||
export KUBECONFIG={{ kubeconfig }}
|
|
||||||
kubectl delete namespace ceph-test --ignore-not-found
|
|
||||||
when: test_app is succeeded
|
|
||||||
|
|
||||||
- name: Summary
|
|
||||||
debug:
|
|
||||||
msg:
|
|
||||||
- "Ceph RBD CSI setup complete!"
|
|
||||||
- "Storage class 'ceph-rbd' is now available for direct Ceph RBD access"
|
|
||||||
- "You can now create PVCs with storageClassName: ceph-rbd"
|
|
||||||
- "This provides better performance than NFS-based access"
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup MariaDB in Container
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 301
|
|
||||||
mariadb_root_password: "dOtPgrVnkIW1zwfjvW9rSw"
|
|
||||||
wavelog_password: "m4icNmGTRtOMgrNxsxEdrw"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Configure DNS in container
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "echo 'nameserver 9.9.9.9' > /etc/resolv.conf"
|
|
||||||
|
|
||||||
- name: Update container packages
|
|
||||||
shell: pct exec {{ ct_id }} -- apt-get update
|
|
||||||
register: apt_update
|
|
||||||
retries: 3
|
|
||||||
delay: 5
|
|
||||||
until: apt_update.rc == 0
|
|
||||||
|
|
||||||
- name: Install MariaDB Server
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
apt-get install -y mariadb-server mariadb-client
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Start and enable MariaDB
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- systemctl enable mariadb
|
|
||||||
pct exec {{ ct_id }} -- systemctl start mariadb
|
|
||||||
|
|
||||||
- name: Secure MariaDB installation
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "mysql -u root << 'EOF'
|
|
||||||
-- Set root password
|
|
||||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mariadb_root_password }}';
|
|
||||||
|
|
||||||
-- Create root user for remote access
|
|
||||||
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mariadb_root_password }}';
|
|
||||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
|
||||||
|
|
||||||
-- Remove anonymous users
|
|
||||||
DELETE FROM mysql.user WHERE User='';
|
|
||||||
|
|
||||||
-- Remove test database
|
|
||||||
DROP DATABASE IF EXISTS test;
|
|
||||||
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
|
|
||||||
|
|
||||||
-- Reload privileges
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
EOF"
|
|
||||||
|
|
||||||
- name: Configure MariaDB for network access
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- sed -i 's/^bind-address.*=.*/bind-address = 0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
|
|
||||||
pct exec {{ ct_id }} -- systemctl restart mariadb
|
|
||||||
|
|
||||||
- name: Create Wavelog database and user
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- mysql -u root -p'{{ mariadb_root_password }}' << 'EOF'
|
|
||||||
CREATE DATABASE IF NOT EXISTS wavelog CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
CREATE USER IF NOT EXISTS 'wavelog'@'%' IDENTIFIED BY '{{ wavelog_password }}';
|
|
||||||
GRANT ALL PRIVILEGES ON wavelog.* TO 'wavelog'@'%';
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Test database connections
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- mysql -u root -p'{{ mariadb_root_password }}' -e "SELECT VERSION();"
|
|
||||||
pct exec {{ ct_id }} -- mysql -u wavelog -p'{{ wavelog_password }}' wavelog -e "SELECT DATABASE();"
|
|
||||||
register: db_test
|
|
||||||
|
|
||||||
- name: Save all credentials
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
MariaDB Container Credentials
|
|
||||||
=============================
|
|
||||||
Created: {{ ansible_date_time.iso8601 }}
|
|
||||||
|
|
||||||
Container Details:
|
|
||||||
- Container ID: {{ ct_id }}
|
|
||||||
- Host: lab02
|
|
||||||
- IP Address: 10.0.19.6
|
|
||||||
- Port: 3306
|
|
||||||
|
|
||||||
Root Credentials:
|
|
||||||
- Username: root
|
|
||||||
- Password: {{ mariadb_root_password }}
|
|
||||||
- Connection: mysql -h 10.0.19.6 -u root -p'{{ mariadb_root_password }}'
|
|
||||||
|
|
||||||
Wavelog Database:
|
|
||||||
- Database: wavelog
|
|
||||||
- Username: wavelog
|
|
||||||
- Password: {{ wavelog_password }}
|
|
||||||
- Connection: mysql -h 10.0.19.6 -u wavelog -p'{{ wavelog_password }}' wavelog
|
|
||||||
|
|
||||||
Test Results:
|
|
||||||
{{ db_test.stdout }}
|
|
||||||
dest: "./mariadb_all_credentials.txt"
|
|
||||||
mode: '0600'
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Update Kubernetes secret for Wavelog
|
|
||||||
shell: |
|
|
||||||
kubectl create secret generic wavelog-db-secret \
|
|
||||||
--from-literal=password="{{ wavelog_password }}" \
|
|
||||||
--dry-run=client -o yaml | kubectl apply -f - -n wavelog
|
|
||||||
environment:
|
|
||||||
KUBECONFIG: "{{ playbook_dir }}/kubeconfig"
|
|
||||||
delegate_to: localhost
|
|
||||||
|
|
||||||
- name: Display summary
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
MariaDB setup completed successfully!
|
|
||||||
|
|
||||||
Root password: {{ mariadb_root_password }}
|
|
||||||
Wavelog password: {{ wavelog_password }}
|
|
||||||
|
|
||||||
All credentials saved to: ./mariadb_all_credentials.txt
|
|
||||||
Kubernetes secret updated: wavelog-db-secret
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup NFS export for CephFS
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
nfs_export_path: /mnt/cephfs-kubernetes
|
|
||||||
k8s_network: "10.0.19.0/24"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Install NFS server
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- nfs-kernel-server
|
|
||||||
- ceph-fuse
|
|
||||||
state: present
|
|
||||||
update_cache: yes
|
|
||||||
|
|
||||||
- name: Create CephFS mount point
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
- name: Mount CephFS
|
|
||||||
mount:
|
|
||||||
path: "{{ nfs_export_path }}"
|
|
||||||
src: "10.0.16.231,10.0.16.232,10.0.16.233:/"
|
|
||||||
fstype: ceph
|
|
||||||
opts: "name=kubernetes,secretfile=/etc/ceph/client.kubernetes.key"
|
|
||||||
state: mounted
|
|
||||||
|
|
||||||
- name: Create Kubernetes storage directories
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}/{{ item }}"
|
|
||||||
state: directory
|
|
||||||
mode: '0777'
|
|
||||||
owner: nobody
|
|
||||||
group: nogroup
|
|
||||||
loop:
|
|
||||||
- volumes
|
|
||||||
- volumes/adguard
|
|
||||||
- volumes/nodered
|
|
||||||
- shared
|
|
||||||
|
|
||||||
- name: Ensure world-writable permissions on CephFS mount
|
|
||||||
file:
|
|
||||||
path: "{{ nfs_export_path }}"
|
|
||||||
mode: '0777'
|
|
||||||
recurse: yes
|
|
||||||
|
|
||||||
- name: Configure NFS exports
|
|
||||||
lineinfile:
|
|
||||||
path: /etc/exports
|
|
||||||
line: "{{ nfs_export_path }} {{ k8s_network }}(rw,sync,no_subtree_check,no_root_squash,no_all_squash)"
|
|
||||||
create: yes
|
|
||||||
notify: restart nfs
|
|
||||||
|
|
||||||
- name: Export NFS shares
|
|
||||||
command: exportfs -ra
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
handlers:
|
|
||||||
- name: restart nfs
|
|
||||||
service:
|
|
||||||
name: nfs-kernel-server
|
|
||||||
state: restarted
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup PostgreSQL with PostGIS in LXC
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
postgres_version: 16
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Check if container is running
|
|
||||||
command: pct status {{ ct_id }}
|
|
||||||
register: ct_status
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Start container if stopped
|
|
||||||
command: pct start {{ ct_id }}
|
|
||||||
when: ct_status.rc == 0 and 'stopped' in ct_status.stdout
|
|
||||||
|
|
||||||
- name: Wait for container to be ready
|
|
||||||
wait_for:
|
|
||||||
host: 10.0.19.5
|
|
||||||
port: 22
|
|
||||||
timeout: 60
|
|
||||||
delay: 5
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Check if PostgreSQL is already installed
|
|
||||||
shell: pct exec {{ ct_id }} -- which psql || echo "not installed"
|
|
||||||
register: psql_check
|
|
||||||
changed_when: false
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Update package list
|
|
||||||
shell: pct exec {{ ct_id }} -- apt-get update -y
|
|
||||||
when: ct_status.rc == 0 and "'not installed' in psql_check.stdout"
|
|
||||||
|
|
||||||
- name: Install PostgreSQL
|
|
||||||
shell: pct exec {{ ct_id }} -- bash -c "export DEBIAN_FRONTEND=noninteractive && apt-get install -y postgresql postgresql-contrib"
|
|
||||||
when: ct_status.rc == 0 and "'not installed' in psql_check.stdout"
|
|
||||||
|
|
||||||
- name: Start PostgreSQL service
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
systemctl enable postgresql
|
|
||||||
systemctl start postgresql
|
|
||||||
systemctl status postgresql
|
|
||||||
"
|
|
||||||
register: pg_status
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Show PostgreSQL status
|
|
||||||
debug:
|
|
||||||
var: pg_status.stdout_lines
|
|
||||||
when: pg_status is defined
|
|
||||||
|
|
||||||
- name: Get PostgreSQL version
|
|
||||||
shell: pct exec {{ ct_id }} -- ls /etc/postgresql/
|
|
||||||
register: pg_dir
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Configure PostgreSQL for network access
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
# Get actual PostgreSQL version
|
|
||||||
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | head -1)
|
|
||||||
|
|
||||||
# If no PostgreSQL directory found, exit
|
|
||||||
if [ -z \"\$PG_VERSION\" ]; then
|
|
||||||
echo 'PostgreSQL not found'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configure postgresql.conf
|
|
||||||
sed -i \"s/#listen_addresses = 'localhost'/listen_addresses = '*'/g\" /etc/postgresql/\$PG_VERSION/main/postgresql.conf
|
|
||||||
|
|
||||||
# Configure pg_hba.conf properly
|
|
||||||
echo '# TYPE DATABASE USER ADDRESS METHOD' > /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'local all postgres peer' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'local all all peer' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'host all all 127.0.0.1/32 scram-sha-256' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'host all all ::1/128 scram-sha-256' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.0.19.0/24 md5' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.0.16.0/22 md5' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
echo 'host all all 10.42.0.0/16 md5' >> /etc/postgresql/\$PG_VERSION/main/pg_hba.conf
|
|
||||||
|
|
||||||
# Restart PostgreSQL
|
|
||||||
systemctl restart postgresql
|
|
||||||
"
|
|
||||||
register: pg_config_result
|
|
||||||
|
|
||||||
- name: Verify pg_hba.conf was updated
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | head -1)
|
|
||||||
if [ -n \"\$PG_VERSION\" ]; then
|
|
||||||
echo '=== PostgreSQL pg_hba.conf ==='
|
|
||||||
cat /etc/postgresql/\$PG_VERSION/main/pg_hba.conf | grep -E '10.0.19|10.42|10.0.16'
|
|
||||||
else
|
|
||||||
echo 'PostgreSQL not found'
|
|
||||||
fi
|
|
||||||
"
|
|
||||||
register: pg_hba_verify
|
|
||||||
|
|
||||||
- name: Display pg_hba.conf entries
|
|
||||||
debug:
|
|
||||||
var: pg_hba_verify.stdout_lines
|
|
||||||
when: pg_hba_verify is defined
|
|
||||||
|
|
||||||
- name: Install sudo if missing
|
|
||||||
shell: pct exec {{ ct_id }} -- apt-get install -y sudo
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Create databases and users
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- su - postgres -c "psql << 'EOF'
|
|
||||||
-- Drop existing if needed and recreate
|
|
||||||
DROP DATABASE IF EXISTS forgejo;
|
|
||||||
DROP USER IF EXISTS forgejo;
|
|
||||||
CREATE USER forgejo WITH PASSWORD 'fj8K3n2Qp9Lx5mW7';
|
|
||||||
CREATE DATABASE forgejo OWNER forgejo;
|
|
||||||
\c forgejo
|
|
||||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE forgejo TO forgejo;
|
|
||||||
|
|
||||||
-- Create other databases as needed
|
|
||||||
DROP DATABASE IF EXISTS apps;
|
|
||||||
DROP USER IF EXISTS appuser;
|
|
||||||
CREATE USER appuser WITH PASSWORD 'AppPass2024!';
|
|
||||||
CREATE DATABASE apps OWNER appuser;
|
|
||||||
\c apps
|
|
||||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE apps TO appuser;
|
|
||||||
EOF"
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Configure firewall
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- bash -c "
|
|
||||||
apt-get install -y ufw
|
|
||||||
ufw allow 22/tcp
|
|
||||||
ufw allow 5432/tcp
|
|
||||||
ufw --force enable
|
|
||||||
"
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Wait for PostgreSQL to be ready
|
|
||||||
wait_for:
|
|
||||||
host: 10.0.19.5
|
|
||||||
port: 5432
|
|
||||||
timeout: 30
|
|
||||||
delay: 2
|
|
||||||
|
|
||||||
- name: Test PostgreSQL connectivity
|
|
||||||
shell: |
|
|
||||||
pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();" || echo "PostgreSQL query failed"
|
|
||||||
register: pg_test
|
|
||||||
when: ct_status.rc == 0
|
|
||||||
|
|
||||||
- name: Display connection info
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL with PostGIS installed successfully!
|
|
||||||
|
|
||||||
Connection details:
|
|
||||||
- Host: 10.0.19.5
|
|
||||||
- Port: 5432
|
|
||||||
- Version: PostgreSQL {{ postgres_version }} with PostGIS 3
|
|
||||||
|
|
||||||
Databases:
|
|
||||||
- forgejo (user: forgejo, pass: fj8K3n2Qp9Lx5mW7)
|
|
||||||
- apps (user: appuser, pass: AppPass2024!)
|
|
||||||
|
|
||||||
From Kubernetes pods, connect using:
|
|
||||||
postgresql://forgejo:fj8K3n2Qp9Lx5mW7@10.0.19.5:5432/forgejo
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
---
|
|
||||||
- name: Setup Wavelog Database in MariaDB
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
mysql_container_id: 301
|
|
||||||
wavelog_password: "m4icNmGTRtOMgrNxsxEdrw"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Create Wavelog database and user
|
|
||||||
shell: |
|
|
||||||
pct exec {{ mysql_container_id }} -- bash -c "mysql -u root <<EOF
|
|
||||||
CREATE DATABASE IF NOT EXISTS wavelog;
|
|
||||||
CREATE USER IF NOT EXISTS 'wavelog'@'%' IDENTIFIED BY '{{ wavelog_password }}';
|
|
||||||
GRANT ALL PRIVILEGES ON wavelog.* TO 'wavelog'@'%';
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
EOF"
|
|
||||||
register: db_creation
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: If root needs password, try with socket authentication
|
|
||||||
shell: |
|
|
||||||
pct exec {{ mysql_container_id }} -- bash -c "mysql <<EOF
|
|
||||||
CREATE DATABASE IF NOT EXISTS wavelog;
|
|
||||||
CREATE USER IF NOT EXISTS 'wavelog'@'%' IDENTIFIED BY '{{ wavelog_password }}';
|
|
||||||
GRANT ALL PRIVILEGES ON wavelog.* TO 'wavelog'@'%';
|
|
||||||
FLUSH PRIVILEGES;
|
|
||||||
EOF"
|
|
||||||
when: db_creation.rc != 0
|
|
||||||
|
|
||||||
- name: Test Wavelog database connection
|
|
||||||
shell: |
|
|
||||||
pct exec {{ mysql_container_id }} -- mysql -u wavelog -p'{{ wavelog_password }}' -e "SELECT DATABASE();" wavelog
|
|
||||||
register: test_result
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Display result
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
Database setup completed!
|
|
||||||
Host: 10.0.19.6
|
|
||||||
Port: 3306
|
|
||||||
Database: wavelog
|
|
||||||
Username: wavelog
|
|
||||||
Password: {{ wavelog_password }}
|
|
||||||
|
|
||||||
Test result: {{ test_result.stdout | default('Failed to connect') }}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
# SSH Configuration for git.w5isp.com access
|
|
||||||
# This config allows users to SSH to git.w5isp.com for Git operations
|
|
||||||
# while still allowing direct SSH to caddy.w5isp.com
|
|
||||||
|
|
||||||
Host git.w5isp.com
|
|
||||||
HostName caddy.w5isp.com
|
|
||||||
Port 2222
|
|
||||||
User git
|
|
||||||
|
|
||||||
Host caddy.w5isp.com
|
|
||||||
HostName caddy.w5isp.com
|
|
||||||
Port 22
|
|
||||||
User graham
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
# Caddy reverse proxy configuration
|
|
||||||
# Managed by Ansible - do not edit manually
|
|
||||||
|
|
||||||
# Forgejo Git server
|
|
||||||
git.w5isp.com {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://100.109.233.14 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# APRS application
|
|
||||||
aprs.me {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://100.93.178.105 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
|
|
||||||
# Enable WebSocket support
|
|
||||||
header_up Upgrade {http.request.header.Upgrade}
|
|
||||||
header_up Connection {http.request.header.Connection}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Jellyfin media server
|
|
||||||
jellyfin.w5isp.com {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://10.0.16.1:8096 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Immich photo management
|
|
||||||
photos.w5isp.com {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://10.0.16.1:2283 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
|
|
||||||
# Immich requires these additional headers for proper operation
|
|
||||||
header_up X-Forwarded-For {remote}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ghost blog
|
|
||||||
w5isp.com {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://100.127.248.71 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
|
|
||||||
# Ghost requires these headers
|
|
||||||
header_up X-Forwarded-For {remote}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wavelog amateur radio logging
|
|
||||||
log.w5isp.com {
|
|
||||||
# Caddy will automatically obtain Let's Encrypt certificates
|
|
||||||
|
|
||||||
reverse_proxy http://100.112.57.20 {
|
|
||||||
# Tell backend that SSL is handled by proxy
|
|
||||||
header_up Host {host}
|
|
||||||
header_up X-Real-IP {remote}
|
|
||||||
header_up X-Forwarded-Proto https
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
|
|
||||||
# Wavelog requires these headers
|
|
||||||
header_up X-Forwarded-For {remote}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add more entries below as needed
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
- name: Check CephFS capacity
|
|
||||||
hosts: proxmox[0]
|
|
||||||
become: true
|
|
||||||
tasks:
|
|
||||||
- name: Check Ceph cluster capacity
|
|
||||||
command: ceph df
|
|
||||||
register: ceph_df
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display Ceph capacity
|
|
||||||
debug:
|
|
||||||
var: ceph_df.stdout_lines
|
|
||||||
|
|
||||||
- name: Get CephFS status
|
|
||||||
command: ceph fs status kubernetes-shared
|
|
||||||
register: cephfs_status
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display CephFS status
|
|
||||||
debug:
|
|
||||||
var: cephfs_status.stdout_lines
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
- name: Upgrade PostgreSQL to 16 and Install PostGIS
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Add PostgreSQL APT repository
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | apt-key add - && echo 'deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
|
|
||||||
|
|
||||||
- name: Update apt cache
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get update -qq
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16 postgresql-client-16
|
|
||||||
|
|
||||||
- name: Check current PostgreSQL clusters
|
|
||||||
command: pct exec {{ ct_id }} -- pg_lsclusters
|
|
||||||
register: clusters
|
|
||||||
|
|
||||||
- name: Display current clusters
|
|
||||||
debug:
|
|
||||||
msg: "{{ clusters.stdout }}"
|
|
||||||
|
|
||||||
- name: Drop old PostgreSQL 16 cluster if exists
|
|
||||||
command: pct exec {{ ct_id }} -- pg_dropcluster 16 main --stop
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Upgrade cluster from 15 to 16
|
|
||||||
command: pct exec {{ ct_id }} -- pg_upgradecluster 15 main
|
|
||||||
|
|
||||||
- name: Install PostGIS for PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3
|
|
||||||
|
|
||||||
- name: Enable PostGIS in APRS database
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -p 5433 -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
|
|
||||||
- name: Switch to port 5432 for PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "sed -i 's/port = 5433/port = 5432/' /etc/postgresql/16/main/postgresql.conf && systemctl restart postgresql@16-main"
|
|
||||||
|
|
||||||
- name: Stop PostgreSQL 15
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl stop postgresql@15-main
|
|
||||||
|
|
||||||
- name: Verify upgrade
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();"
|
|
||||||
register: version
|
|
||||||
|
|
||||||
- name: Display results
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL upgrade completed!
|
|
||||||
{{ version.stdout }}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
---
|
|
||||||
- name: Upgrade PostgreSQL 15 to 16 in LXC
|
|
||||||
hosts: lab02
|
|
||||||
become: true
|
|
||||||
vars:
|
|
||||||
ct_id: 300
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Stop PostgreSQL 15 service
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl stop postgresql@15-main
|
|
||||||
|
|
||||||
- name: Add PostgreSQL APT repository key
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -"
|
|
||||||
|
|
||||||
- name: Add PostgreSQL APT repository
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "echo 'deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
|
|
||||||
|
|
||||||
- name: Update apt cache
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get update
|
|
||||||
|
|
||||||
- name: Install PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16 postgresql-client-16 postgresql-contrib-16
|
|
||||||
|
|
||||||
- name: Stop PostgreSQL 16 (auto-started after install)
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl stop postgresql@16-main
|
|
||||||
|
|
||||||
- name: Upgrade the cluster from 15 to 16
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres /usr/lib/postgresql/16/bin/pg_upgrade -b /usr/lib/postgresql/15/bin -B /usr/lib/postgresql/16/bin -d /var/lib/postgresql/15/main -D /var/lib/postgresql/16/main -o "-c config_file=/etc/postgresql/15/main/postgresql.conf" -O "-c config_file=/etc/postgresql/16/main/postgresql.conf"
|
|
||||||
|
|
||||||
- name: Copy PostgreSQL 15 configuration
|
|
||||||
command: pct exec {{ ct_id }} -- bash -c "cp /etc/postgresql/15/main/postgresql.conf /etc/postgresql/16/main/ && cp /etc/postgresql/15/main/pg_hba.conf /etc/postgresql/16/main/"
|
|
||||||
|
|
||||||
- name: Update PostgreSQL 16 port to 5432
|
|
||||||
command: pct exec {{ ct_id }} -- sed -i "s/port = 5433/port = 5432/" /etc/postgresql/16/main/postgresql.conf
|
|
||||||
|
|
||||||
- name: Start PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl start postgresql@16-main
|
|
||||||
|
|
||||||
- name: Enable PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl enable postgresql@16-main
|
|
||||||
|
|
||||||
- name: Disable PostgreSQL 15
|
|
||||||
command: pct exec {{ ct_id }} -- systemctl disable postgresql@15-main
|
|
||||||
|
|
||||||
- name: Install PostGIS for PostgreSQL 16
|
|
||||||
command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3
|
|
||||||
|
|
||||||
- name: Enable PostGIS in APRS database
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
|
|
||||||
- name: Enable PostGIS in Forgejo database (if needed)
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -d forgejo -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Verify PostgreSQL version
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();"
|
|
||||||
register: pg_version
|
|
||||||
|
|
||||||
- name: Verify PostGIS installation
|
|
||||||
command: pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();"
|
|
||||||
register: postgis_version
|
|
||||||
|
|
||||||
- name: Display results
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
PostgreSQL upgrade completed!
|
|
||||||
|
|
||||||
{{ pg_version.stdout }}
|
|
||||||
|
|
||||||
PostGIS Version in APRS database:
|
|
||||||
{{ postgis_version.stdout }}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: ghcr.io/wavelog/wavelog:latest
|
|
||||||
env:
|
|
||||||
- name: CI_ENV
|
|
||||||
value: "docker"
|
|
||||||
- name: WAVELOG_DB_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: WAVELOG_DB_PORT
|
|
||||||
value: "3306"
|
|
||||||
- name: WAVELOG_DB_NAME
|
|
||||||
value: "wavelog"
|
|
||||||
- name: WAVELOG_DB_USER
|
|
||||||
value: "wavelog"
|
|
||||||
- name: WAVELOG_DB_PASS
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /var/www/html/application/config/docker
|
|
||||||
- name: uploads
|
|
||||||
mountPath: /var/www/html/uploads
|
|
||||||
- name: userdata
|
|
||||||
mountPath: /var/www/html/userdata
|
|
||||||
- name: backup
|
|
||||||
mountPath: /var/www/html/backup
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: ghcr-pull-secret
|
|
||||||
volumes:
|
|
||||||
- name: config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-config
|
|
||||||
- name: uploads
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-uploads
|
|
||||||
- name: userdata
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-userdata
|
|
||||||
- name: backup
|
|
||||||
emptyDir: {}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: php:8.2-apache
|
|
||||||
env:
|
|
||||||
- name: DATABASE_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: DATABASE_PORT
|
|
||||||
value: "3306"
|
|
||||||
- name: DATABASE_NAME
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DATABASE_USER
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DATABASE_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /var/www/html
|
|
||||||
lifecycle:
|
|
||||||
postStart:
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- /bin/bash
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
# Install dependencies if not already installed
|
|
||||||
if [ ! -f /var/www/html/.deps_installed ]; then
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
git \
|
|
||||||
unzip \
|
|
||||||
libpng-dev \
|
|
||||||
libjpeg-dev \
|
|
||||||
libfreetype6-dev \
|
|
||||||
libzip-dev \
|
|
||||||
libicu-dev \
|
|
||||||
mariadb-client \
|
|
||||||
curl \
|
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
|
||||||
&& docker-php-ext-install gd mysqli pdo pdo_mysql zip intl \
|
|
||||||
&& a2enmod rewrite \
|
|
||||||
&& touch /var/www/html/.deps_installed
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clone Wavelog if not exists
|
|
||||||
if [ ! -f /var/www/html/index.php ]; then
|
|
||||||
cd /tmp
|
|
||||||
git clone https://github.com/wavelog/wavelog.git
|
|
||||||
cp -R wavelog/* /var/www/html/
|
|
||||||
cp -R wavelog/.* /var/www/html/ 2>/dev/null || true
|
|
||||||
chown -R www-data:www-data /var/www/html
|
|
||||||
chmod -R 755 /var/www/html
|
|
||||||
|
|
||||||
# Create uploads directory
|
|
||||||
mkdir -p /var/www/html/uploads
|
|
||||||
chown -R www-data:www-data /var/www/html/uploads
|
|
||||||
chmod -R 777 /var/www/html/uploads
|
|
||||||
fi
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "200m"
|
|
||||||
limits:
|
|
||||||
memory: "1Gi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-data
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: wavelog-uploads
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 5Gi
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: wavelog-userdata
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 5Gi
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: wavelog-config
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 1Gi
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: ghcr.io/wavelog/wavelog:latest
|
|
||||||
env:
|
|
||||||
- name: CI_ENV
|
|
||||||
value: "docker"
|
|
||||||
- name: DB_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: DB_NAME
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DB_USER
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DB_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /var/www/html/application/config/docker
|
|
||||||
- name: uploads
|
|
||||||
mountPath: /var/www/html/uploads
|
|
||||||
- name: userdata
|
|
||||||
mountPath: /var/www/html/userdata
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: ghcr-pull-secret
|
|
||||||
volumes:
|
|
||||||
- name: config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-config
|
|
||||||
- name: uploads
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-uploads
|
|
||||||
- name: userdata
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-userdata
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: wavelog
|
|
||||||
type: LoadBalancer
|
|
||||||
ports:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 80
|
|
||||||
targetPort: 80
|
|
||||||
name: http
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: wavelog-tailscale
|
|
||||||
namespace: wavelog
|
|
||||||
annotations:
|
|
||||||
tailscale.com/expose: "true"
|
|
||||||
tailscale.com/hostname: "wavelog"
|
|
||||||
tailscale.com/funnel: "false"
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
app: wavelog
|
|
||||||
type: LoadBalancer
|
|
||||||
loadBalancerClass: tailscale
|
|
||||||
ports:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 80
|
|
||||||
targetPort: 80
|
|
||||||
name: http
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: ghcr.io/wavelog/wavelog:latest
|
|
||||||
env:
|
|
||||||
- name: CI_ENV
|
|
||||||
value: "docker"
|
|
||||||
- name: WAVELOG_DB_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: WAVELOG_DB_PORT
|
|
||||||
value: "3306"
|
|
||||||
- name: WAVELOG_DB_NAME
|
|
||||||
value: "wavelog"
|
|
||||||
- name: WAVELOG_DB_USER
|
|
||||||
value: "wavelog"
|
|
||||||
- name: WAVELOG_DB_PASS
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /var/www/html/application/config/docker
|
|
||||||
- name: uploads
|
|
||||||
mountPath: /var/www/html/uploads
|
|
||||||
- name: userdata
|
|
||||||
mountPath: /var/www/html/userdata
|
|
||||||
- name: backup
|
|
||||||
mountPath: /var/www/html/backup
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: ghcr-pull-secret
|
|
||||||
volumes:
|
|
||||||
- name: config
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-config
|
|
||||||
- name: uploads
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-uploads
|
|
||||||
- name: userdata
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-userdata
|
|
||||||
- name: backup
|
|
||||||
emptyDir: {}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
initContainers:
|
|
||||||
- name: setup
|
|
||||||
image: php:8.2-apache
|
|
||||||
command:
|
|
||||||
- /bin/bash
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
echo "Installing dependencies..."
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
git unzip libpng-dev libjpeg-dev libfreetype6-dev \
|
|
||||||
libzip-dev libicu-dev mariadb-client curl \
|
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
|
||||||
&& docker-php-ext-install gd mysqli pdo pdo_mysql zip intl
|
|
||||||
|
|
||||||
echo "Cloning Wavelog..."
|
|
||||||
cd /tmp
|
|
||||||
git clone https://github.com/wavelog/wavelog.git
|
|
||||||
cp -R wavelog/* /var/www/html/
|
|
||||||
cp -R wavelog/.* /var/www/html/ 2>/dev/null || true
|
|
||||||
|
|
||||||
# Create config directory
|
|
||||||
mkdir -p /var/www/html/application/config/docker
|
|
||||||
|
|
||||||
# Create database.php config
|
|
||||||
cat > /var/www/html/application/config/database.php << 'EOF'
|
|
||||||
<?php
|
|
||||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
||||||
|
|
||||||
$active_group = 'default';
|
|
||||||
$query_builder = TRUE;
|
|
||||||
|
|
||||||
$db['default'] = array(
|
|
||||||
'dsn' => '',
|
|
||||||
'hostname' => '10.0.19.6',
|
|
||||||
'username' => 'wavelog',
|
|
||||||
'password' => 'm4icNmGTRtOMgrNxsxEdrw',
|
|
||||||
'database' => 'wavelog',
|
|
||||||
'dbdriver' => 'mysqli',
|
|
||||||
'dbprefix' => '',
|
|
||||||
'pconnect' => FALSE,
|
|
||||||
'db_debug' => FALSE,
|
|
||||||
'cache_on' => FALSE,
|
|
||||||
'cachedir' => '',
|
|
||||||
'char_set' => 'utf8mb4',
|
|
||||||
'dbcollat' => 'utf8mb4_general_ci',
|
|
||||||
'swap_pre' => '',
|
|
||||||
'encrypt' => FALSE,
|
|
||||||
'compress' => FALSE,
|
|
||||||
'stricton' => FALSE,
|
|
||||||
'failover' => array(),
|
|
||||||
'save_queries' => TRUE
|
|
||||||
);
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Set permissions
|
|
||||||
chown -R www-data:www-data /var/www/html
|
|
||||||
chmod -R 755 /var/www/html
|
|
||||||
chmod -R 777 /var/www/html/uploads
|
|
||||||
chmod -R 777 /var/www/html/application/cache
|
|
||||||
chmod -R 777 /var/www/html/application/logs
|
|
||||||
chmod -R 777 /var/www/html/userdata
|
|
||||||
|
|
||||||
# Enable Apache rewrite module
|
|
||||||
a2enmod rewrite
|
|
||||||
|
|
||||||
echo "Setup complete!"
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /var/www/html
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: php:8.2-apache
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /var/www/html
|
|
||||||
env:
|
|
||||||
- name: APACHE_DOCUMENT_ROOT
|
|
||||||
value: /var/www/html
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-data
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: wavelog
|
|
||||||
namespace: wavelog
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: wavelog
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: wavelog
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: wavelog
|
|
||||||
image: php:8.2-apache
|
|
||||||
env:
|
|
||||||
- name: CI_ENV
|
|
||||||
value: "production"
|
|
||||||
- name: DB_HOST
|
|
||||||
value: "10.0.19.6"
|
|
||||||
- name: DB_NAME
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DB_USER
|
|
||||||
value: "wavelog"
|
|
||||||
- name: DB_PASS
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: wavelog-db-secret
|
|
||||||
key: password
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
name: http
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /var/www/html
|
|
||||||
command:
|
|
||||||
- /bin/bash
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
# Install dependencies
|
|
||||||
apt-get update && apt-get install -y \
|
|
||||||
git \
|
|
||||||
unzip \
|
|
||||||
libpng-dev \
|
|
||||||
libjpeg-dev \
|
|
||||||
libfreetype6-dev \
|
|
||||||
libzip-dev \
|
|
||||||
libicu-dev \
|
|
||||||
mariadb-client \
|
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
|
||||||
&& docker-php-ext-install gd mysqli pdo pdo_mysql zip intl \
|
|
||||||
&& a2enmod rewrite
|
|
||||||
|
|
||||||
# Clone Wavelog if not exists
|
|
||||||
if [ ! -d /var/www/html/index.php ]; then
|
|
||||||
cd /tmp
|
|
||||||
git clone https://github.com/wavelog/wavelog.git
|
|
||||||
cp -R wavelog/* /var/www/html/
|
|
||||||
chown -R www-data:www-data /var/www/html
|
|
||||||
|
|
||||||
# Create database config
|
|
||||||
cat > /var/www/html/application/config/database.php << EOF
|
|
||||||
<?php
|
|
||||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
||||||
|
|
||||||
\$active_group = 'default';
|
|
||||||
\$query_builder = TRUE;
|
|
||||||
|
|
||||||
\$db['default'] = array(
|
|
||||||
'dsn' => '',
|
|
||||||
'hostname' => '${DB_HOST}',
|
|
||||||
'username' => '${DB_USER}',
|
|
||||||
'password' => '${DB_PASS}',
|
|
||||||
'database' => '${DB_NAME}',
|
|
||||||
'dbdriver' => 'mysqli',
|
|
||||||
'dbprefix' => '',
|
|
||||||
'pconnect' => FALSE,
|
|
||||||
'db_debug' => (ENVIRONMENT !== 'production'),
|
|
||||||
'cache_on' => FALSE,
|
|
||||||
'cachedir' => '',
|
|
||||||
'char_set' => 'utf8mb4',
|
|
||||||
'dbcollat' => 'utf8mb4_general_ci',
|
|
||||||
'swap_pre' => '',
|
|
||||||
'encrypt' => FALSE,
|
|
||||||
'compress' => FALSE,
|
|
||||||
'stricton' => FALSE,
|
|
||||||
'failover' => array(),
|
|
||||||
'save_queries' => TRUE
|
|
||||||
);
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start Apache
|
|
||||||
apache2-foreground
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "512Mi"
|
|
||||||
cpu: "500m"
|
|
||||||
volumes:
|
|
||||||
- name: data
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: wavelog-data
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
Wavelog Database Credentials
|
|
||||||
============================
|
|
||||||
|
|
||||||
MariaDB Container: 301 on lab02
|
|
||||||
Host: 10.0.19.6
|
|
||||||
Port: 3306
|
|
||||||
Database: wavelog
|
|
||||||
Username: wavelog
|
|
||||||
Password: m4icNmGTRtOMgrNxsxEdrw
|
|
||||||
|
|
||||||
Note: Database needs to be created manually in MariaDB container 301.
|
|
||||||
The root password for MariaDB may be required.
|
|
||||||
|
|
||||||
Connection String:
|
|
||||||
mysql://wavelog:m4icNmGTRtOMgrNxsxEdrw@10.0.19.6:3306/wavelog
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
||||||
#cloud-config
|
|
||||||
# Minimal cloud-init configuration for Debian 13 base template
|
|
||||||
|
|
||||||
# Update and upgrade packages on first boot
|
|
||||||
package_update: true
|
|
||||||
package_upgrade: true
|
|
||||||
|
|
||||||
# Configure timezone
|
|
||||||
timezone: America/Chicago
|
|
||||||
|
|
||||||
# Install essential packages
|
|
||||||
packages:
|
|
||||||
# System utilities
|
|
||||||
- sudo
|
|
||||||
- curl
|
|
||||||
- wget
|
|
||||||
- git
|
|
||||||
- vim
|
|
||||||
- nano
|
|
||||||
- tmux
|
|
||||||
- htop
|
|
||||||
- iotop
|
|
||||||
- rsync
|
|
||||||
- net-tools
|
|
||||||
- dnsutils
|
|
||||||
- traceroute
|
|
||||||
- mtr-tiny
|
|
||||||
- tcpdump
|
|
||||||
- nmap
|
|
||||||
- netcat-openbsd
|
|
||||||
|
|
||||||
# Development tools
|
|
||||||
- build-essential
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
- python3-venv
|
|
||||||
- jq
|
|
||||||
- fzf
|
|
||||||
- zsh
|
|
||||||
|
|
||||||
# System monitoring
|
|
||||||
- sysstat
|
|
||||||
- smartmontools
|
|
||||||
- lm-sensors
|
|
||||||
|
|
||||||
# Time synchronization
|
|
||||||
- chrony
|
|
||||||
|
|
||||||
# Security
|
|
||||||
- fail2ban
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
# Container runtime (optional)
|
|
||||||
- docker.io
|
|
||||||
- docker-compose
|
|
||||||
|
|
||||||
# Other useful tools
|
|
||||||
- apt-transport-https
|
|
||||||
- ca-certificates
|
|
||||||
- gnupg
|
|
||||||
- lsb-release
|
|
||||||
- software-properties-common
|
|
||||||
|
|
||||||
# Create users with sudo access
|
|
||||||
users:
|
|
||||||
- name: graham
|
|
||||||
groups: sudo,docker
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_import_id:
|
|
||||||
- gh:gmcintire
|
|
||||||
|
|
||||||
- name: andy
|
|
||||||
groups: sudo,docker
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_import_id:
|
|
||||||
- gh:nsnw
|
|
||||||
|
|
||||||
- name: ansible
|
|
||||||
uid: 10001
|
|
||||||
groups: sudo,docker
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_authorized_keys:
|
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5aTtW3lgF9PfV8sTIxZfbvo6dUBMq5C5zJrXy6mwdb5UK9xvqty5Vlh6F1FqYlZgvIyR7NqLbXnKqsvLVGdkTm9VEXGlNcbPJ3ilbhc3OJPX0k63CwokU6nSztXguE1v3KB7JjXiM0dj7ujuDzAGfPZNClR6u06NjIamzeWcQnsJV3P8rLxa7ppvFgBp0K1N1pMb3AUqXOutsOUjSvs5C4H+GMmKYCYNpPGbfKNDLfB9vYLPYv/ynF1lDDzBDL6gy0PnDX6lXC9jvfPWSKNu5lgIUc6p9J++I/ERGktbGPvEaLPeJjgIJPbVLwvnmCLDj2VBmvu2cVE+oXWjLJLF7y8T1cZA0d7aH1TWHcaFPNd3nsPbWGOA3PtMoNRLN/6b7mA7QAKCEBVcR1cZ8c5wQ7ilcLETrNBmJLPpBQa7tLvCx8Q8KPNmtZX6dMKR1o7yj5mXq7Slzo6RTdKLpDqODPVPmGboChMQWFEvGCKxVYLDuvS8iXHdkRE+C9xwqNis= ansible
|
|
||||||
|
|
||||||
# Configure SSH
|
|
||||||
ssh_pwauth: false
|
|
||||||
disable_root: true
|
|
||||||
|
|
||||||
# SSH configuration
|
|
||||||
write_files:
|
|
||||||
- path: /etc/ssh/sshd_config.d/99-custom.conf
|
|
||||||
content: |
|
|
||||||
PermitRootLogin no
|
|
||||||
PasswordAuthentication no
|
|
||||||
ChallengeResponseAuthentication no
|
|
||||||
UsePAM yes
|
|
||||||
X11Forwarding yes
|
|
||||||
PrintMotd no
|
|
||||||
AcceptEnv LANG LC_*
|
|
||||||
Banner /etc/issue.net
|
|
||||||
|
|
||||||
- path: /etc/issue.net
|
|
||||||
content: |
|
|
||||||
******************************************************************
|
|
||||||
* *
|
|
||||||
* This system is for authorized users only. All activity is *
|
|
||||||
* monitored and reported. Unauthorized access is prohibited. *
|
|
||||||
* *
|
|
||||||
******************************************************************
|
|
||||||
|
|
||||||
- path: /etc/sudoers.d/90-cloud-init-users
|
|
||||||
content: |
|
|
||||||
# Created by cloud-init
|
|
||||||
graham ALL=(ALL) NOPASSWD:ALL
|
|
||||||
andy ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ansible ALL=(ALL) NOPASSWD:ALL
|
|
||||||
permissions: '0440'
|
|
||||||
|
|
||||||
- path: /etc/motd
|
|
||||||
content: |
|
|
||||||
Welcome to Debian 13 (Trixie)
|
|
||||||
|
|
||||||
System Information:
|
|
||||||
* Documentation: https://www.debian.org/doc/
|
|
||||||
* Support: https://www.debian.org/support
|
|
||||||
|
|
||||||
- path: /etc/chrony/sources.d/custom.sources
|
|
||||||
content: |
|
|
||||||
pool 0.us.pool.ntp.org iburst
|
|
||||||
pool 1.us.pool.ntp.org iburst
|
|
||||||
pool 2.us.pool.ntp.org iburst
|
|
||||||
pool 3.us.pool.ntp.org iburst
|
|
||||||
|
|
||||||
- path: /etc/sysctl.d/99-custom.conf
|
|
||||||
content: |
|
|
||||||
# IP forwarding for containers/k8s
|
|
||||||
net.ipv4.ip_forward = 1
|
|
||||||
net.ipv6.conf.all.forwarding = 1
|
|
||||||
|
|
||||||
# Increase inotify limits for containers
|
|
||||||
fs.inotify.max_user_watches = 524288
|
|
||||||
fs.inotify.max_user_instances = 512
|
|
||||||
|
|
||||||
# Network performance tuning
|
|
||||||
net.core.rmem_max = 134217728
|
|
||||||
net.core.wmem_max = 134217728
|
|
||||||
net.ipv4.tcp_rmem = 4096 87380 134217728
|
|
||||||
net.ipv4.tcp_wmem = 4096 65536 134217728
|
|
||||||
|
|
||||||
# Security hardening
|
|
||||||
net.ipv4.conf.all.rp_filter = 1
|
|
||||||
net.ipv4.conf.default.rp_filter = 1
|
|
||||||
net.ipv4.tcp_syncookies = 1
|
|
||||||
net.ipv4.conf.all.accept_source_route = 0
|
|
||||||
net.ipv6.conf.all.accept_source_route = 0
|
|
||||||
|
|
||||||
- path: /etc/security/limits.d/99-custom.conf
|
|
||||||
content: |
|
|
||||||
# Increase limits for containers
|
|
||||||
* soft nofile 65536
|
|
||||||
* hard nofile 65536
|
|
||||||
* soft nproc 32768
|
|
||||||
* hard nproc 32768
|
|
||||||
|
|
||||||
# Configure firewall (ufw)
|
|
||||||
ufw:
|
|
||||||
enabled: true
|
|
||||||
rules:
|
|
||||||
- port: 22
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: SSH
|
|
||||||
- port: 80
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: HTTP
|
|
||||||
- port: 443
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: HTTPS
|
|
||||||
|
|
||||||
# Run commands on first boot
|
|
||||||
runcmd:
|
|
||||||
# Configure fail2ban
|
|
||||||
- systemctl enable fail2ban
|
|
||||||
- systemctl start fail2ban
|
|
||||||
|
|
||||||
# Enable and configure Docker
|
|
||||||
- systemctl enable docker
|
|
||||||
- systemctl start docker
|
|
||||||
- usermod -aG docker graham
|
|
||||||
- usermod -aG docker andy
|
|
||||||
- usermod -aG docker ansible
|
|
||||||
|
|
||||||
# Apply sysctl settings
|
|
||||||
- sysctl -p /etc/sysctl.d/99-custom.conf
|
|
||||||
|
|
||||||
# Configure chrony
|
|
||||||
- systemctl restart chrony
|
|
||||||
|
|
||||||
# Secure shared memory
|
|
||||||
- echo "tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0" >> /etc/fstab
|
|
||||||
- mount -o remount /run/shm
|
|
||||||
|
|
||||||
# Create common directories
|
|
||||||
- mkdir -p /opt/scripts /opt/configs
|
|
||||||
|
|
||||||
# Set proper permissions
|
|
||||||
- chmod 644 /etc/issue.net
|
|
||||||
- chmod 440 /etc/sudoers.d/90-cloud-init-users
|
|
||||||
|
|
||||||
# Update locate database
|
|
||||||
- updatedb
|
|
||||||
|
|
||||||
# Configure automatic updates
|
|
||||||
apt:
|
|
||||||
preserve_sources_list: true
|
|
||||||
conf: |
|
|
||||||
APT::Periodic::Update-Package-Lists "1";
|
|
||||||
APT::Periodic::Download-Upgradeable-Packages "1";
|
|
||||||
APT::Periodic::AutocleanInterval "7";
|
|
||||||
APT::Periodic::Unattended-Upgrade "1";
|
|
||||||
|
|
||||||
# Power state change timeout
|
|
||||||
power_state:
|
|
||||||
delay: now
|
|
||||||
mode: reboot
|
|
||||||
message: Initial configuration complete, rebooting...
|
|
||||||
timeout: 30
|
|
||||||
condition: true
|
|
||||||
|
|
@ -1,225 +0,0 @@
|
||||||
#cloud-config
|
|
||||||
# Cloud-init configuration for Debian 13 Vultr server with Caddy proxy and Tailscale
|
|
||||||
|
|
||||||
# Update and upgrade packages on first boot
|
|
||||||
package_update: true
|
|
||||||
package_upgrade: true
|
|
||||||
|
|
||||||
# Configure hostname
|
|
||||||
hostname: caddy
|
|
||||||
|
|
||||||
# Configure timezone
|
|
||||||
timezone: America/Chicago
|
|
||||||
|
|
||||||
# Install packages
|
|
||||||
packages:
|
|
||||||
# Include all base packages
|
|
||||||
- sudo
|
|
||||||
- curl
|
|
||||||
- wget
|
|
||||||
- git
|
|
||||||
- vim
|
|
||||||
- tmux
|
|
||||||
- htop
|
|
||||||
- rsync
|
|
||||||
- net-tools
|
|
||||||
- dnsutils
|
|
||||||
- build-essential
|
|
||||||
- python3
|
|
||||||
- python3-pip
|
|
||||||
- apt-transport-https
|
|
||||||
- ca-certificates
|
|
||||||
- gnupg
|
|
||||||
- lsb-release
|
|
||||||
- software-properties-common
|
|
||||||
- fail2ban
|
|
||||||
- ufw
|
|
||||||
|
|
||||||
# Caddy and web server tools
|
|
||||||
- debian-keyring
|
|
||||||
- debian-archive-keyring
|
|
||||||
|
|
||||||
# Create users with sudo access
|
|
||||||
users:
|
|
||||||
- name: graham
|
|
||||||
groups: sudo
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_import_id:
|
|
||||||
- gh:gmcintire
|
|
||||||
|
|
||||||
- name: andy
|
|
||||||
groups: sudo
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_import_id:
|
|
||||||
- gh:nsnw
|
|
||||||
|
|
||||||
- name: ansible
|
|
||||||
uid: 10001
|
|
||||||
groups: sudo
|
|
||||||
shell: /bin/bash
|
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
||||||
ssh_authorized_keys:
|
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5aTtW3lgF9PfV8sTIxZfbvo6dUBMq5C5zJrXy6mwdb5UK9xvqty5Vlh6F1FqYlZgvIyR7NqLbXnKqsvLVGdkTm9VEXGlNcbPJ3ilbhc3OJPX0k63CwokU6nSztXguE1v3KB7JjXiM0dj7ujuDzAGfPZNClR6u06NjIamzeWcQnsJV3P8rLxa7ppvFgBp0K1N1pMb3AUqXOutsOUjSvs5C4H+GMmKYCYNpPGbfKNDLfB9vYLPYv/ynF1lDDzBDL6gy0PnDX6lXC9jvfPWSKNu5lgIUc6p9J++I/ERGktbGPvEaLPeJjgIJPbVLwvnmCLDj2VBmvu2cVE+oXWjLJLF7y8T1cZA0d7aH1TWHcaFPNd3nsPbWGOA3PtMoNRLN/6b7mA7QAKCEBVcR1cZ8c5wQ7ilcLETrNBmJLPpBQa7tLvCx8Q8KPNmtZX6dMKR1o7yj5mXq7Slzo6RTdKLpDqODPVPmGboChMQWFEvGCKxVYLDuvS8iXHdkRE+C9xwqNis= ansible
|
|
||||||
|
|
||||||
# Configure SSH
|
|
||||||
ssh_pwauth: false
|
|
||||||
disable_root: true
|
|
||||||
|
|
||||||
# Write configuration files
|
|
||||||
write_files:
|
|
||||||
- path: /etc/ssh/sshd_config.d/99-custom.conf
|
|
||||||
content: |
|
|
||||||
PermitRootLogin no
|
|
||||||
PasswordAuthentication no
|
|
||||||
Banner /etc/issue.net
|
|
||||||
|
|
||||||
- path: /etc/issue.net
|
|
||||||
content: |
|
|
||||||
******************************************************************
|
|
||||||
* Authorized access only. All activity is monitored. *
|
|
||||||
******************************************************************
|
|
||||||
|
|
||||||
- path: /etc/apt/sources.list.d/caddy-stable.list
|
|
||||||
content: |
|
|
||||||
deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
|
|
||||||
|
|
||||||
- path: /etc/caddy/Caddyfile
|
|
||||||
content: |
|
|
||||||
# Global options
|
|
||||||
{
|
|
||||||
# Email for Let's Encrypt
|
|
||||||
email admin@example.com
|
|
||||||
|
|
||||||
# Enable the admin endpoint
|
|
||||||
admin off
|
|
||||||
}
|
|
||||||
|
|
||||||
# Default site - return 404 for undefined hosts
|
|
||||||
:80 {
|
|
||||||
respond 404
|
|
||||||
}
|
|
||||||
|
|
||||||
# Example reverse proxy configuration
|
|
||||||
# example.com {
|
|
||||||
# reverse_proxy localhost:8080
|
|
||||||
# }
|
|
||||||
permissions: '0644'
|
|
||||||
owner: root:root
|
|
||||||
|
|
||||||
- path: /etc/sysctl.d/99-tailscale.conf
|
|
||||||
content: |
|
|
||||||
# Tailscale UDP GRO fix
|
|
||||||
net.ipv4.udp_rmem_min = 131072
|
|
||||||
net.ipv4.udp_wmem_min = 131072
|
|
||||||
net.core.rmem_default = 131072
|
|
||||||
net.core.wmem_default = 131072
|
|
||||||
net.core.netdev_max_backlog = 5000
|
|
||||||
|
|
||||||
- path: /opt/scripts/install-tailscale.sh
|
|
||||||
content: |
|
|
||||||
#!/bin/bash
|
|
||||||
# Install Tailscale
|
|
||||||
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
|
|
||||||
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y tailscale
|
|
||||||
|
|
||||||
# Enable and start tailscaled
|
|
||||||
systemctl enable tailscaled
|
|
||||||
systemctl start tailscaled
|
|
||||||
|
|
||||||
# If TAILSCALE_KEY is provided, authenticate
|
|
||||||
if [ -n "$TAILSCALE_KEY" ]; then
|
|
||||||
tailscale up --authkey="$TAILSCALE_KEY" --accept-routes --hostname=$(hostname)
|
|
||||||
fi
|
|
||||||
permissions: '0755'
|
|
||||||
|
|
||||||
- path: /opt/scripts/setup-caddy.sh
|
|
||||||
content: |
|
|
||||||
#!/bin/bash
|
|
||||||
# Ensure Caddy starts after network is ready
|
|
||||||
mkdir -p /etc/systemd/system/caddy.service.d
|
|
||||||
cat > /etc/systemd/system/caddy.service.d/override.conf <<EOF
|
|
||||||
[Unit]
|
|
||||||
After=network-online.target
|
|
||||||
Wants=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
# Restart on failure
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5s
|
|
||||||
EOF
|
|
||||||
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable caddy
|
|
||||||
systemctl start caddy
|
|
||||||
permissions: '0755'
|
|
||||||
|
|
||||||
# Configure firewall
|
|
||||||
ufw:
|
|
||||||
enabled: true
|
|
||||||
rules:
|
|
||||||
- port: 22
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: SSH
|
|
||||||
- port: 80
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: HTTP
|
|
||||||
- port: 443
|
|
||||||
protocol: tcp
|
|
||||||
rule: allow
|
|
||||||
comment: HTTPS
|
|
||||||
- port: 41641
|
|
||||||
protocol: udp
|
|
||||||
rule: allow
|
|
||||||
from_any: true
|
|
||||||
comment: Tailscale
|
|
||||||
|
|
||||||
# Run commands on first boot
|
|
||||||
runcmd:
|
|
||||||
# Add Caddy GPG key and install
|
|
||||||
- curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
|
||||||
- apt-get update
|
|
||||||
- apt-get install -y caddy
|
|
||||||
|
|
||||||
# Apply sysctl settings
|
|
||||||
- sysctl -p /etc/sysctl.d/99-tailscale.conf
|
|
||||||
|
|
||||||
# Create Caddy directories
|
|
||||||
- mkdir -p /etc/caddy/sites-enabled
|
|
||||||
- chown -R caddy:caddy /etc/caddy
|
|
||||||
|
|
||||||
# Install Tailscale
|
|
||||||
- /opt/scripts/install-tailscale.sh
|
|
||||||
|
|
||||||
# Setup Caddy service
|
|
||||||
- /opt/scripts/setup-caddy.sh
|
|
||||||
|
|
||||||
# Configure fail2ban for Caddy
|
|
||||||
- |
|
|
||||||
cat > /etc/fail2ban/jail.d/caddy.conf <<EOF
|
|
||||||
[caddy-status]
|
|
||||||
enabled = true
|
|
||||||
filter = caddy-status
|
|
||||||
logpath = /var/log/caddy/access.log
|
|
||||||
maxretry = 5
|
|
||||||
bantime = 600
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Enable services
|
|
||||||
- systemctl enable fail2ban
|
|
||||||
- systemctl start fail2ban
|
|
||||||
|
|
||||||
# Final message
|
|
||||||
final_message: "Debian 13 Caddy proxy setup complete! System ready after $UPTIME seconds"
|
|
||||||
|
|
||||||
# Power state - don't reboot automatically for proxy servers
|
|
||||||
power_state:
|
|
||||||
delay: now
|
|
||||||
mode: poweroff
|
|
||||||
message: Initial configuration complete
|
|
||||||
condition: false
|
|
||||||
74
home/cluster/add-node3-to-etcd.sh
Executable file
74
home/cluster/add-node3-to-etcd.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Script to properly join node3 to existing K3s etcd cluster
|
||||||
|
# Run this script ON node3
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "=== Adding node3 to existing K3s etcd cluster ==="
|
||||||
|
|
||||||
|
# Step 1: Stop K3s and clean up
|
||||||
|
echo "Stopping K3s and cleaning up..."
|
||||||
|
sudo systemctl stop k3s || true
|
||||||
|
sudo systemctl stop k3s-agent || true
|
||||||
|
|
||||||
|
# Remove server data to prevent conflicts
|
||||||
|
echo "Cleaning up previous server data..."
|
||||||
|
sudo rm -rf /var/lib/rancher/k3s/server
|
||||||
|
|
||||||
|
# Step 2: Get the token from an existing server
|
||||||
|
echo ""
|
||||||
|
echo "You need to get the cluster token from node1 or node2."
|
||||||
|
echo "On node1 or node2, run:"
|
||||||
|
echo " sudo cat /var/lib/rancher/k3s/server/token"
|
||||||
|
echo ""
|
||||||
|
read -p "Enter the K3s cluster token: " K3S_TOKEN
|
||||||
|
|
||||||
|
# Step 3: Create proper K3s configuration for joining existing cluster
|
||||||
|
echo "Creating K3s configuration..."
|
||||||
|
sudo mkdir -p /etc/rancher/k3s
|
||||||
|
|
||||||
|
# Important: We need to specify this is joining an existing cluster
|
||||||
|
cat << EOF | sudo tee /etc/rancher/k3s/config.yaml
|
||||||
|
# Join existing cluster - do not initialize new one
|
||||||
|
server: "https://10.0.101.21:6443"
|
||||||
|
token: "${K3S_TOKEN}"
|
||||||
|
|
||||||
|
# Additional configuration
|
||||||
|
tls-san:
|
||||||
|
- "10.0.101.23"
|
||||||
|
- "node3"
|
||||||
|
|
||||||
|
node-ip: "10.0.101.23"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Step 4: Uninstall K3s agent if it exists
|
||||||
|
if [ -f /usr/local/bin/k3s-agent-uninstall.sh ]; then
|
||||||
|
echo "Uninstalling K3s agent..."
|
||||||
|
sudo /usr/local/bin/k3s-agent-uninstall.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 5: Install K3s as server joining the existing cluster
|
||||||
|
echo "Installing K3s as server (joining existing cluster)..."
|
||||||
|
curl -sfL https://get.k3s.io | sh -s - server \
|
||||||
|
--server https://10.0.101.21:6443 \
|
||||||
|
--token "${K3S_TOKEN}"
|
||||||
|
|
||||||
|
# Step 6: Wait for services to start
|
||||||
|
echo "Waiting for K3s to start..."
|
||||||
|
sleep 20
|
||||||
|
|
||||||
|
# Step 7: Check status
|
||||||
|
echo "Checking K3s status..."
|
||||||
|
sudo systemctl status k3s --no-pager || true
|
||||||
|
sudo journalctl -u k3s -n 50 --no-pager
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Setup complete ==="
|
||||||
|
echo "If you see errors about etcd already being initialized, that's expected."
|
||||||
|
echo "Check from your local machine with:"
|
||||||
|
echo " kubectl get nodes"
|
||||||
|
echo ""
|
||||||
|
echo "The node should now show roles: control-plane,etcd,master"
|
||||||
|
echo ""
|
||||||
|
echo "To check etcd cluster members from node1:"
|
||||||
|
echo " sudo k3s etcdctl member list"
|
||||||
74
home/cluster/aprs/postgres-deployment-normal.yaml
Normal file
74
home/cluster/aprs/postgres-deployment-normal.yaml
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres-aprs
|
||||||
|
namespace: aprs
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres-aprs
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
clusterIP: None
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: postgres-aprs
|
||||||
|
namespace: aprs
|
||||||
|
spec:
|
||||||
|
serviceName: postgres-aprs
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres-aprs
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres-aprs
|
||||||
|
spec:
|
||||||
|
terminationGracePeriodSeconds: 600 # 10 minutes to shutdown gracefully
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: postgis/postgis:17-3.4
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: postgres-aprs-secret
|
||||||
|
env:
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
volumeMounts:
|
||||||
|
- name: postgres-storage
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
||||||
|
initialDelaySeconds: 300 # 5 minutes to start
|
||||||
|
periodSeconds: 30 # Check every 30s
|
||||||
|
timeoutSeconds: 10 # 10s timeout for probe
|
||||||
|
failureThreshold: 20 # Allow 20 failures (10 minutes)
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
||||||
|
initialDelaySeconds: 300 # 5 minutes to start
|
||||||
|
periodSeconds: 30 # Check every 30s
|
||||||
|
timeoutSeconds: 10 # 10s timeout for probe
|
||||||
|
failureThreshold: 20 # Allow 20 failures (10 minutes)
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: postgres-storage
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 100Gi
|
||||||
55
home/cluster/aprs/postgres-deployment-repair.yaml
Normal file
55
home/cluster/aprs/postgres-deployment-repair.yaml
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres-aprs
|
||||||
|
namespace: aprs
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres-aprs
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
|
clusterIP: None
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: postgres-aprs
|
||||||
|
namespace: aprs
|
||||||
|
spec:
|
||||||
|
serviceName: postgres-aprs
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: postgres-aprs
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: postgres-aprs
|
||||||
|
spec:
|
||||||
|
terminationGracePeriodSeconds: 3600 # 1 hour to shutdown gracefully
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: postgis/postgis:17-3.4
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: postgres-aprs-secret
|
||||||
|
env:
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
volumeMounts:
|
||||||
|
- name: postgres-storage
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
# NO HEALTH CHECKS - Pod will run indefinitely even if unhealthy
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: postgres-storage
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
storageClassName: longhorn
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 100Gi
|
||||||
|
|
@ -28,6 +28,7 @@ spec:
|
||||||
labels:
|
labels:
|
||||||
app: postgres-aprs
|
app: postgres-aprs
|
||||||
spec:
|
spec:
|
||||||
|
terminationGracePeriodSeconds: 600 # 10 minutes to shutdown gracefully
|
||||||
containers:
|
containers:
|
||||||
- name: postgres
|
- name: postgres
|
||||||
image: postgis/postgis:17-3.4
|
image: postgis/postgis:17-3.4
|
||||||
|
|
@ -48,16 +49,20 @@ spec:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
- -c
|
- -c
|
||||||
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 300 # 5 minutes to start
|
||||||
periodSeconds: 10
|
periodSeconds: 30 # Check every 30s
|
||||||
|
timeoutSeconds: 10 # 10s timeout for probe
|
||||||
|
failureThreshold: 20 # Allow 20 failures (10 minutes)
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
exec:
|
exec:
|
||||||
command:
|
command:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
- -c
|
- -c
|
||||||
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
- pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 300 # 5 minutes to start
|
||||||
periodSeconds: 5
|
periodSeconds: 30 # Check every 30s
|
||||||
|
timeoutSeconds: 10 # 10s timeout for probe
|
||||||
|
failureThreshold: 20 # Allow 20 failures (10 minutes)
|
||||||
volumeClaimTemplates:
|
volumeClaimTemplates:
|
||||||
- metadata:
|
- metadata:
|
||||||
name: postgres-storage
|
name: postgres-storage
|
||||||
|
|
|
||||||
10
home/cluster/aprs/postgres-normal-mode.sh
Executable file
10
home/cluster/aprs/postgres-normal-mode.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Restore normal mode for PostgreSQL (with health checks)
|
||||||
|
|
||||||
|
echo "Restoring PostgreSQL normal mode (with health checks)..."
|
||||||
|
export KUBECONFIG=/Users/graham/dev/infra/home/ansible/kubeconfig
|
||||||
|
|
||||||
|
kubectl apply -f postgres-deployment-normal.yaml
|
||||||
|
|
||||||
|
echo "PostgreSQL is now in normal mode with health checks enabled"
|
||||||
|
echo "Monitor with: kubectl logs -n aprs postgres-aprs-0 -f"
|
||||||
11
home/cluster/aprs/postgres-repair-mode.sh
Executable file
11
home/cluster/aprs/postgres-repair-mode.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Enable repair mode for PostgreSQL (no health checks)
|
||||||
|
|
||||||
|
echo "Enabling PostgreSQL repair mode (no health checks)..."
|
||||||
|
export KUBECONFIG=/Users/graham/dev/infra/home/ansible/kubeconfig
|
||||||
|
|
||||||
|
kubectl apply -f postgres-deployment-repair.yaml
|
||||||
|
|
||||||
|
echo "PostgreSQL is now in repair mode - it will run indefinitely without health checks"
|
||||||
|
echo "Monitor with: kubectl logs -n aprs postgres-aprs-0 -f"
|
||||||
|
echo "To restore normal mode, run: ./postgres-normal-mode.sh"
|
||||||
49
home/cluster/check-ha-readiness.sh
Executable file
49
home/cluster/check-ha-readiness.sh
Executable file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Check K3s cluster HA readiness
|
||||||
|
|
||||||
|
echo "=== K3s Cluster HA Readiness Check ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check nodes
|
||||||
|
echo "1. Node Status:"
|
||||||
|
kubectl get nodes -o wide
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check LoadBalancer services
|
||||||
|
echo "2. LoadBalancer Services (need to be accessible from any node):"
|
||||||
|
kubectl get svc -A | grep LoadBalancer
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check NodePort services
|
||||||
|
echo "3. NodePort Services (can be accessed on any node):"
|
||||||
|
kubectl get svc -A -o json | jq -r '.items[] | select(.spec.type=="NodePort") | "\(.metadata.namespace)/\(.metadata.name) - NodePorts: \(.spec.ports[].nodePort)"'
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check Traefik/Ingress
|
||||||
|
echo "4. Ingress Controller Status:"
|
||||||
|
kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik
|
||||||
|
kubectl get svc -n kube-system traefik
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check critical pods distribution
|
||||||
|
echo "5. Critical Pod Distribution:"
|
||||||
|
echo "Traefik pods:"
|
||||||
|
kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik -o wide
|
||||||
|
|
||||||
|
echo -e "\nAPRS pods:"
|
||||||
|
kubectl get pods -n aprs -o wide
|
||||||
|
|
||||||
|
echo -e "\nAll pods on node1 (will be affected during update):"
|
||||||
|
kubectl get pods -A -o wide | grep node1
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Recommendations
|
||||||
|
echo "=== Recommendations ==="
|
||||||
|
echo ""
|
||||||
|
echo "For MikroTik failover, ensure:"
|
||||||
|
echo "1. All services use NodePort or have hostPort configured"
|
||||||
|
echo "2. Configure MikroTik NAT to forward to NodePort on all nodes"
|
||||||
|
echo "3. Or use MikroTik Netwatch for automatic failover"
|
||||||
|
echo ""
|
||||||
|
echo "Current service ports:"
|
||||||
|
kubectl get svc -A | grep -E "NodePort|LoadBalancer" | awk '{print $2 " (" $1 "): " $6}'
|
||||||
44
home/cluster/high-availability-setup.md
Normal file
44
home/cluster/high-availability-setup.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# High Availability Setup for K3s Cluster
|
||||||
|
|
||||||
|
## Current Situation
|
||||||
|
- **node1** (10.0.101.21): Has public IP 204.110.191.2, currently being updated
|
||||||
|
- **node2** (10.0.101.22): No public IP
|
||||||
|
- **node3** (10.0.101.23): No public IP
|
||||||
|
|
||||||
|
## Solution Options
|
||||||
|
|
||||||
|
### Option 1: Floating IP (Recommended if your provider supports it)
|
||||||
|
Use a floating/virtual IP that can be moved between nodes:
|
||||||
|
|
||||||
|
1. Get a floating IP from your provider
|
||||||
|
2. Use Keepalived to manage automatic failover
|
||||||
|
3. Install MetalLB or Kube-VIP for in-cluster load balancing
|
||||||
|
|
||||||
|
### Option 2: External Load Balancer (Best for production)
|
||||||
|
Use your hosting provider's load balancer or set up HAProxy/Nginx:
|
||||||
|
|
||||||
|
1. Set up an external load balancer pointing to all 3 nodes
|
||||||
|
2. Configure health checks on port 6443 (K3s API)
|
||||||
|
3. For services, use NodePort and configure LB to forward to all nodes
|
||||||
|
|
||||||
|
### Option 3: DNS Round-Robin with Health Checks (Simple but less reliable)
|
||||||
|
Configure multiple A records with health checking:
|
||||||
|
|
||||||
|
1. Add A records for all node IPs to your domain
|
||||||
|
2. Use a DNS provider that supports health checks (like Route53)
|
||||||
|
3. Automatically remove unhealthy nodes from rotation
|
||||||
|
|
||||||
|
### Option 4: Tailscale + Caddy on Separate Host (Quick solution)
|
||||||
|
Since you have Tailscale, use a separate small VPS as a reverse proxy:
|
||||||
|
|
||||||
|
1. Get a small VPS with public IP
|
||||||
|
2. Install Tailscale and join your network
|
||||||
|
3. Install Caddy to reverse proxy to cluster services
|
||||||
|
4. Point DNS to this VPS instead of directly to cluster
|
||||||
|
|
||||||
|
## Immediate Solution: Configure Services for High Availability
|
||||||
|
|
||||||
|
While node1 is down, ensure your apps remain accessible:
|
||||||
|
|
||||||
|
### 1. Configure Pod Anti-Affinity
|
||||||
|
Ensure critical pods run on different nodes:
|
||||||
177
home/cluster/mikrotik-ha-setup.md
Normal file
177
home/cluster/mikrotik-ha-setup.md
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
# High Availability Setup with MikroTik
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Using MikroTik's built-in features to ensure K3s cluster remains accessible when node1 is down.
|
||||||
|
|
||||||
|
## Option 1: MikroTik Load Balancing with PCC (Per Connection Classifier)
|
||||||
|
|
||||||
|
### On MikroTik Router:
|
||||||
|
```mikrotik
|
||||||
|
# 1. Create address list for K3s nodes
|
||||||
|
/ip firewall address-list
|
||||||
|
add address=10.0.101.21 list=k3s-nodes comment="node1"
|
||||||
|
add address=10.0.101.22 list=k3s-nodes comment="node2"
|
||||||
|
add address=10.0.101.23 list=k3s-nodes comment="node3"
|
||||||
|
|
||||||
|
# 2. Create NAT rules for incoming traffic to distribute to nodes
|
||||||
|
# For HTTP/HTTPS traffic (ports 80, 443)
|
||||||
|
/ip firewall nat
|
||||||
|
add chain=dstnat action=dst-nat protocol=tcp dst-address=204.110.191.2 \
|
||||||
|
dst-port=80 to-addresses=10.0.101.21-10.0.101.23 to-ports=80 \
|
||||||
|
comment="K3s HTTP load balance"
|
||||||
|
|
||||||
|
add chain=dstnat action=dst-nat protocol=tcp dst-address=204.110.191.2 \
|
||||||
|
dst-port=443 to-addresses=10.0.101.21-10.0.101.23 to-ports=443 \
|
||||||
|
comment="K3s HTTPS load balance"
|
||||||
|
|
||||||
|
# 3. Add connection marking for load balancing
|
||||||
|
/ip firewall mangle
|
||||||
|
add chain=prerouting action=mark-connection new-connection-mark=k3s-conn-1 \
|
||||||
|
dst-address=204.110.191.2 dst-port=80,443 protocol=tcp \
|
||||||
|
per-connection-classifier=both-addresses:3/0
|
||||||
|
|
||||||
|
add chain=prerouting action=mark-connection new-connection-mark=k3s-conn-2 \
|
||||||
|
dst-address=204.110.191.2 dst-port=80,443 protocol=tcp \
|
||||||
|
per-connection-classifier=both-addresses:3/1
|
||||||
|
|
||||||
|
add chain=prerouting action=mark-connection new-connection-mark=k3s-conn-3 \
|
||||||
|
dst-address=204.110.191.2 dst-port=80,443 protocol=tcp \
|
||||||
|
per-connection-classifier=both-addresses:3/2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Option 2: MikroTik with VRRP (Virtual Router Redundancy Protocol)
|
||||||
|
|
||||||
|
### Prerequisites:
|
||||||
|
- Assign additional IPs to each node for VRRP
|
||||||
|
- Configure MikroTik to route to VRRP virtual IP
|
||||||
|
|
||||||
|
### On Each K3s Node:
|
||||||
|
```bash
|
||||||
|
# Install keepalived
|
||||||
|
sudo apt-get update && sudo apt-get install -y keepalived
|
||||||
|
|
||||||
|
# Create keepalived configuration
|
||||||
|
sudo tee /etc/keepalived/keepalived.conf << EOF
|
||||||
|
vrrp_instance VI_1 {
|
||||||
|
state BACKUP # All nodes start as BACKUP
|
||||||
|
interface eth0 # Your network interface
|
||||||
|
virtual_router_id 51 # Same on all nodes
|
||||||
|
priority $(hostname | grep -o '[0-9]*')0 # node1=10, node2=20, node3=30
|
||||||
|
advert_int 1
|
||||||
|
authentication {
|
||||||
|
auth_type PASS
|
||||||
|
auth_pass k3scluster
|
||||||
|
}
|
||||||
|
virtual_ipaddress {
|
||||||
|
10.0.101.100/24 # Virtual IP for cluster
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Start keepalived
|
||||||
|
sudo systemctl enable --now keepalived
|
||||||
|
```
|
||||||
|
|
||||||
|
### On MikroTik:
|
||||||
|
```mikrotik
|
||||||
|
# Route public IP traffic to VRRP virtual IP
|
||||||
|
/ip firewall nat
|
||||||
|
add chain=dstnat action=dst-nat protocol=tcp dst-address=204.110.191.2 \
|
||||||
|
dst-port=80,443 to-addresses=10.0.101.100 \
|
||||||
|
comment="K3s VRRP Virtual IP"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Option 3: MikroTik Netwatch with Failover (Simplest)
|
||||||
|
|
||||||
|
This monitors nodes and updates NAT dynamically:
|
||||||
|
|
||||||
|
```mikrotik
|
||||||
|
# 1. Create scripts for failover
|
||||||
|
/system script
|
||||||
|
add name="k3s-use-node1" source={
|
||||||
|
/ip firewall nat set [find comment="K3s HTTP"] to-addresses=10.0.101.21
|
||||||
|
/ip firewall nat set [find comment="K3s HTTPS"] to-addresses=10.0.101.21
|
||||||
|
:log info "K3s traffic switched to node1"
|
||||||
|
}
|
||||||
|
|
||||||
|
add name="k3s-use-node2" source={
|
||||||
|
/ip firewall nat set [find comment="K3s HTTP"] to-addresses=10.0.101.22
|
||||||
|
/ip firewall nat set [find comment="K3s HTTPS"] to-addresses=10.0.101.22
|
||||||
|
:log info "K3s traffic switched to node2"
|
||||||
|
}
|
||||||
|
|
||||||
|
add name="k3s-use-node3" source={
|
||||||
|
/ip firewall nat set [find comment="K3s HTTP"] to-addresses=10.0.101.23
|
||||||
|
/ip firewall nat set [find comment="K3s HTTPS"] to-addresses=10.0.101.23
|
||||||
|
:log info "K3s traffic switched to node3"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. Create initial NAT rules
|
||||||
|
/ip firewall nat
|
||||||
|
add chain=dstnat action=dst-nat protocol=tcp dst-address=204.110.191.2 \
|
||||||
|
dst-port=80 to-addresses=10.0.101.21 to-ports=80 comment="K3s HTTP"
|
||||||
|
|
||||||
|
add chain=dstnat action=dst-nat protocol=tcp dst-address=204.110.191.2 \
|
||||||
|
dst-port=443 to-addresses=10.0.101.21 to-ports=443 comment="K3s HTTPS"
|
||||||
|
|
||||||
|
# 3. Set up Netwatch monitors
|
||||||
|
/tool netwatch
|
||||||
|
add host=10.0.101.21 interval=10s timeout=5s \
|
||||||
|
down-script={
|
||||||
|
:if ([/tool netwatch get [find host=10.0.101.22] status]="up") do={
|
||||||
|
/system script run k3s-use-node2
|
||||||
|
} else={
|
||||||
|
:if ([/tool netwatch get [find host=10.0.101.23] status]="up") do={
|
||||||
|
/system script run k3s-use-node3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} \
|
||||||
|
up-script="/system script run k3s-use-node1"
|
||||||
|
|
||||||
|
add host=10.0.101.22 interval=10s timeout=5s
|
||||||
|
add host=10.0.101.23 interval=10s timeout=5s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recommended: Configure K3s Services for Any Node Access
|
||||||
|
|
||||||
|
Make sure your services use NodePort or LoadBalancer type:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Example service configuration
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: myapp
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
nodePort: 32080 # This port will be accessible on ALL nodes
|
||||||
|
selector:
|
||||||
|
app: myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
Then configure MikroTik to forward to the NodePort on any available node.
|
||||||
|
|
||||||
|
## Testing the Failover
|
||||||
|
|
||||||
|
1. Verify current routing:
|
||||||
|
```bash
|
||||||
|
curl -v http://204.110.191.2
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Shut down node1:
|
||||||
|
```bash
|
||||||
|
ssh node1 sudo shutdown -h now
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Watch MikroTik logs and verify traffic switches:
|
||||||
|
```mikrotik
|
||||||
|
/log print follow where topics~"info"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Verify service remains accessible:
|
||||||
|
```bash
|
||||||
|
curl -v http://204.110.191.2
|
||||||
|
```
|
||||||
63
home/cluster/update-k3s-cluster.md
Normal file
63
home/cluster/update-k3s-cluster.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
# K3s Cluster Update Instructions
|
||||||
|
|
||||||
|
## Update Order for Multi-Master Cluster
|
||||||
|
|
||||||
|
When updating a multi-master K3s cluster with embedded etcd, follow this order:
|
||||||
|
|
||||||
|
1. **Update node2 first** (secondary master)
|
||||||
|
2. **Update node1 second** (primary master)
|
||||||
|
3. **Update node3 last** (if it's successfully added to etcd cluster)
|
||||||
|
|
||||||
|
## Steps for Each Node
|
||||||
|
|
||||||
|
1. Copy the update script to the node:
|
||||||
|
```bash
|
||||||
|
scp update-k3s-node.sh node2:~/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. SSH to the node and run the script:
|
||||||
|
```bash
|
||||||
|
ssh node2
|
||||||
|
chmod +x update-k3s-node.sh
|
||||||
|
./update-k3s-node.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. When prompted about draining:
|
||||||
|
- Answer **'y'** for production safety (moves pods to other nodes)
|
||||||
|
- Answer **'n'** if you want faster update and can tolerate brief downtime
|
||||||
|
|
||||||
|
4. Monitor the update progress and verify the node comes back online
|
||||||
|
|
||||||
|
## Verification Commands
|
||||||
|
|
||||||
|
From your local machine:
|
||||||
|
```bash
|
||||||
|
# Check all nodes are ready and on correct version
|
||||||
|
kubectl get nodes -o wide
|
||||||
|
|
||||||
|
# Check etcd cluster health (run on any master node)
|
||||||
|
ssh node1 'sudo k3s etcdctl endpoint health'
|
||||||
|
|
||||||
|
# Check for any pods having issues
|
||||||
|
kubectl get pods -A | grep -v Running
|
||||||
|
|
||||||
|
# Check cluster info
|
||||||
|
kubectl cluster-info
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rollback (if needed)
|
||||||
|
|
||||||
|
If something goes wrong, you can rollback to the previous version:
|
||||||
|
```bash
|
||||||
|
# On the affected node
|
||||||
|
sudo systemctl stop k3s
|
||||||
|
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="v1.33.4+k3s1" INSTALL_K3S_SKIP_START=true sh -
|
||||||
|
sudo systemctl start k3s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- The update process will cause a brief disruption to pods on that node
|
||||||
|
- Embedded etcd cluster requires majority of nodes to be online
|
||||||
|
- Always update secondary masters before primary master
|
||||||
|
- Monitor etcd logs during update: `sudo journalctl -u k3s -f | grep etcd`
|
||||||
64
home/cluster/update-k3s-node.sh
Executable file
64
home/cluster/update-k3s-node.sh
Executable file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Script to update K3s on a node to version 1.33.5
|
||||||
|
# Run this script ON each node you want to update
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
NODE_NAME=$(hostname)
|
||||||
|
K3S_VERSION="v1.33.5+k3s1"
|
||||||
|
|
||||||
|
echo "=== Updating K3s on ${NODE_NAME} to ${K3S_VERSION} ==="
|
||||||
|
|
||||||
|
# Step 1: Check current version
|
||||||
|
echo "Current K3s version:"
|
||||||
|
k3s --version
|
||||||
|
|
||||||
|
# Step 2: Drain the node (make workloads move to other nodes)
|
||||||
|
echo ""
|
||||||
|
echo "Do you want to drain this node first? (recommended for safety)"
|
||||||
|
echo "This will move pods to other nodes during the update."
|
||||||
|
read -p "Drain node? (y/n): " DRAIN_NODE
|
||||||
|
|
||||||
|
if [[ "$DRAIN_NODE" == "y" ]]; then
|
||||||
|
echo "Draining node ${NODE_NAME}..."
|
||||||
|
kubectl drain ${NODE_NAME} --ignore-daemonsets --delete-emptydir-data --force --grace-period=60
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 3: Stop K3s service
|
||||||
|
echo ""
|
||||||
|
echo "Stopping K3s service..."
|
||||||
|
sudo systemctl stop k3s
|
||||||
|
|
||||||
|
# Step 4: Download and install new K3s version
|
||||||
|
echo "Installing K3s ${K3S_VERSION}..."
|
||||||
|
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="${K3S_VERSION}" INSTALL_K3S_SKIP_START=true sh -
|
||||||
|
|
||||||
|
# Step 5: Start K3s with new version
|
||||||
|
echo "Starting K3s..."
|
||||||
|
sudo systemctl start k3s
|
||||||
|
|
||||||
|
# Step 6: Wait for node to be ready
|
||||||
|
echo "Waiting for K3s to be ready..."
|
||||||
|
sleep 20
|
||||||
|
|
||||||
|
# Step 7: Check new version
|
||||||
|
echo ""
|
||||||
|
echo "New K3s version:"
|
||||||
|
k3s --version
|
||||||
|
|
||||||
|
# Step 8: Check node status
|
||||||
|
kubectl get node ${NODE_NAME}
|
||||||
|
|
||||||
|
# Step 9: Uncordon the node if it was drained
|
||||||
|
if [[ "$DRAIN_NODE" == "y" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Uncordoning node ${NODE_NAME}..."
|
||||||
|
kubectl uncordon ${NODE_NAME}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Update complete on ${NODE_NAME} ==="
|
||||||
|
echo ""
|
||||||
|
echo "Verify cluster health with:"
|
||||||
|
echo " kubectl get nodes"
|
||||||
|
echo " kubectl get pods -A | grep -v Running"
|
||||||
35
terraform/.gitignore
vendored
35
terraform/.gitignore
vendored
|
|
@ -1,35 +0,0 @@
|
||||||
# Local .terraform directories
|
|
||||||
**/.terraform/*
|
|
||||||
|
|
||||||
# .tfstate files
|
|
||||||
*.tfstate
|
|
||||||
*.tfstate.*
|
|
||||||
|
|
||||||
# Crash log files
|
|
||||||
crash.log
|
|
||||||
crash.*.log
|
|
||||||
|
|
||||||
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
|
|
||||||
# password, private keys, and other secrets. These should not be part of version
|
|
||||||
# control as they are data points which are potentially sensitive and subject
|
|
||||||
# to change depending on the environment.
|
|
||||||
*.tfvars
|
|
||||||
*.tfvars.json
|
|
||||||
|
|
||||||
# Ignore override files as they are usually used to override resources locally and so
|
|
||||||
# are not checked in
|
|
||||||
override.tf
|
|
||||||
override.tf.json
|
|
||||||
*_override.tf
|
|
||||||
*_override.tf.json
|
|
||||||
|
|
||||||
# Include override files you do wish to add to version control using negated pattern
|
|
||||||
# !example_override.tf
|
|
||||||
|
|
||||||
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
|
|
||||||
# example: *tfplan*
|
|
||||||
|
|
||||||
# Ignore CLI configuration files
|
|
||||||
.terraformrc
|
|
||||||
terraform.rc
|
|
||||||
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
# CLAUDE.md
|
|
||||||
|
|
||||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
### Terraform Workflow
|
|
||||||
```bash
|
|
||||||
# Initialize terraform providers
|
|
||||||
terraform init
|
|
||||||
|
|
||||||
# Validate configuration
|
|
||||||
terraform validate
|
|
||||||
|
|
||||||
# Plan changes
|
|
||||||
terraform plan
|
|
||||||
|
|
||||||
# Apply changes
|
|
||||||
terraform apply
|
|
||||||
|
|
||||||
# Show current state
|
|
||||||
terraform show
|
|
||||||
|
|
||||||
# Format terraform files
|
|
||||||
terraform fmt
|
|
||||||
```
|
|
||||||
|
|
||||||
### State Management
|
|
||||||
```bash
|
|
||||||
# List resources in state
|
|
||||||
terraform state list
|
|
||||||
|
|
||||||
# Show specific resource
|
|
||||||
terraform state show <resource_name>
|
|
||||||
|
|
||||||
# Import existing resources
|
|
||||||
terraform import <resource_type>.<name> <id>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
This Terraform codebase manages DNS infrastructure across multiple providers:
|
|
||||||
|
|
||||||
### DNS Providers
|
|
||||||
- **DNSimple**: Primary domain registrar and DNS hosting
|
|
||||||
- **Porkbun**: Alternative DNS provider
|
|
||||||
- **PowerDNS**: Manages reverse DNS zones (204.110.188-191.x ranges)
|
|
||||||
|
|
||||||
### File Organization
|
|
||||||
- `main.tf`: Provider configurations and requirements
|
|
||||||
- `vars.tf`: Variable definitions (⚠️ contains hardcoded credentials that should be moved to environment variables)
|
|
||||||
- `dns_*.tf`: DNS zone and record configurations organized by domain/provider
|
|
||||||
- State is managed locally (`terraform.tfstate`)
|
|
||||||
|
|
||||||
### Managed Domains
|
|
||||||
- w5isp.com
|
|
||||||
- manero.org
|
|
||||||
- mcintire.me
|
|
||||||
- vntx.net, vntx.org
|
|
||||||
- gridmap.org
|
|
||||||
- Reverse DNS zones for 204.110.188-191.x IP ranges
|
|
||||||
|
|
||||||
### Security Considerations
|
|
||||||
**Critical**: API keys and tokens are hardcoded in `vars.tf` defaults. When making changes:
|
|
||||||
1. Never commit new credentials to the repository
|
|
||||||
2. Use environment variables: `export TF_VAR_variable_name=value`
|
|
||||||
3. Or use `-var` flags: `terraform apply -var="dnsimple_token=xxx"`
|
|
||||||
|
|
||||||
### Common Tasks
|
|
||||||
|
|
||||||
#### Adding DNS Records
|
|
||||||
1. Identify the appropriate `dns_*.tf` file for the domain
|
|
||||||
2. Add the record using the appropriate resource type:
|
|
||||||
```hcl
|
|
||||||
resource "dnsimple_zone_record" "example" {
|
|
||||||
zone_name = "domain.com"
|
|
||||||
name = "subdomain"
|
|
||||||
value = "192.168.1.1"
|
|
||||||
type = "A"
|
|
||||||
ttl = 3600
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Importing Existing DNS Records
|
|
||||||
```bash
|
|
||||||
# DNSimple records
|
|
||||||
terraform import dnsimple_zone_record.name {zone_id}_{record_id}
|
|
||||||
|
|
||||||
# PowerDNS records
|
|
||||||
terraform import powerdns_record.name zone.com.:record_name:type
|
|
||||||
```
|
|
||||||
|
|
||||||
### Development Notes
|
|
||||||
- No modules are used; resources are organized by domain/function
|
|
||||||
- No automated testing or CI/CD pipeline exists
|
|
||||||
- Direct commits to main branch are the current workflow
|
|
||||||
- Run `terraform fmt` before committing to ensure consistent formatting
|
|
||||||
Loading…
Add table
Reference in a new issue