ai

Immutable OS Fedora CoreOS Community Building —

Immutable OS Fedora CoreOS Community Building —

Immutable OS และ Fedora CoreOS คืออะไร

Immutable OS Fedora CoreOS Community Building —

Immutable OS คือระบบปฏิบัติการที่ root filesystem เป็น read-only ไม่สามารถแก้ไขได้ขณะรัน การเปลี่ยนแปลงทำผ่าน atomic updates ที่สร้าง filesystem snapshot ใหม่ทั้งหมด ถ้า update มีปัญหาสามารถ rollback ไป version ก่อนหน้าได้ทันที

Fedora CoreOS (FCOS) เป็น immutable Linux distribution ที่ออกแบบมาสำหรับรัน containerized workloads เป็นการรวม Fedora Atomic Host กับ Container Linux (CoreOS) เข้าด้วยกัน ให้ minimal OS ที่มี automatic updates, container runtime (Podman, Docker) และ provisioning ผ่าน Ignition

ข้อดีของ Immutable OS ได้แก่ Security ที่ดีขึ้นเพราะ filesystem ถูก lock ลด attack surface, Reliability จาก atomic updates ที่ rollback ได้, Consistency ทุกเครื่องเหมือนกัน 100% ไม่มี configuration drift, Reproducibility สร้าง environment เดิมได้ทุกครั้ง และ Simplicity ลด management overhead

Immutable OS อื่นๆ ได้แก่ Flatcar Container Linux, Bottlerocket (AWS), Talos Linux (Kubernetes), NixOS (functional package management) และ openSUSE MicroOS แต่ละตัวมี target use case ต่างกัน Fedora CoreOS เหมาะสำหรับ general-purpose container hosting

เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: Eth Coin — คู่มือ Crypto ฉบับสมบูรณ์ 2026

ติดตั้ง Fedora CoreOS ด้วย Ignition

Provision Fedora CoreOS ด้วย Ignition configuration

# === Fedora CoreOS Installation ===



# 1. ติดตั้ง Butane (config transpiler)

# Butane แปลง YAML config เป็น Ignition JSON



# Linux

curl -LO https://github.com/coreos/butane/releases/latest/download/butane-x86_64-unknown-linux-gnu

chmod +x butane-x86_64-unknown-linux-gnu

sudo mv butane-x86_64-unknown-linux-gnu /usr/local/bin/butane



# macOS

brew install butane



# ตรวจสอบ

butane --version



# 2. สร้าง Butane Config

cat > config.bu << 'YAML'

variant: fcos

version: "1.5.0"

passwd:

  users:

    - name: core

      ssh_authorized_keys:

        - ssh-rsa AAAA...your-public-key...

      groups:

        - sudo

        - docker

    - name: admin

      ssh_authorized_keys:

        - ssh-rsa AAAA...admin-key...

      groups:

        - sudo



storage:

  files:

    - path: /etc/hostname

      mode: 0644

      contents:

        inline: fcos-node-1

    

    - path: /etc/sysctl.d/90-custom.conf

      mode: 0644

      contents:

        inline: |

          net.ipv4.ip_forward = 1

          net.core.somaxconn = 65535

          vm.max_map_count = 262144

    

    - path: /etc/zincati/config.d/55-updates-strategy.toml

      mode: 0644

      contents:

        inline: |

          [updates]

          strategy = "periodic"

          [[updates.periodic.window]]

          days = [ "Sun" ]

          start_time = "03:00"

          length_minutes = 120

    

    - path: /opt/scripts/health-check.sh

      mode: 0755

      contents:

        inline: |

          #!/bin/bash

          echo "=== System Health Check ==="

          echo "Hostname: $(hostname)"

          echo "Uptime: $(uptime -p)"

          echo "OS: $(rpm-ostree status --json | jq -r '.deployments[0].version')"

          echo "Containers: $(podman ps -q | wc -l) running"

          echo "Disk: $(df -h / | tail -1 | awk '{print $5}') used"

          echo "Memory: $(free -h | grep Mem | awk '{print $3"/"$2}')"



  directories:

    - path: /opt/containers

      mode: 0755

    - path: /opt/data

      mode: 0755



systemd:

  units:

    - name: podman-auto-update.timer

      enabled: true

    

    - name: health-check.timer

      enabled: true

      contents: |

        [Unit]

        Description=Periodic health check

        [Timer]

        OnCalendar=*:0/15

        [Install]

        WantedBy=timers.target

    

    - name: health-check.service

      contents: |

        [Unit]

        Description=System health check

        [Service]

        Type=oneshot

        ExecStart=/opt/scripts/health-check.sh

YAML



# 3. Transpile to Ignition

butane --pretty --strict config.bu > config.ign



# 4. ติดตั้ง (bare metal)

# Download Fedora CoreOS ISO

curl -LO https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/latest/x86_64/fedora-coreos-live.x86_64.iso



# Install to disk

sudo coreos-installer install /dev/sda \

    --ignition-file config.ign \

    --stream stable



# 5. ติดตั้ง (QEMU/KVM)

IGNITION_CONFIG="$(pwd)/config.ign"

IMAGE="fedora-coreos-qemu.x86_64.qcow2"



qemu-img create -f qcow2 -b "$IMAGE" -F qcow2 fcos-node.qcow2 20G



virt-install \

    --name fcos-node-1 \

    --ram 4096 --vcpus 2 \

    --import \

    --disk fcos-node.qcow2 \

    --os-variant fedora-coreos-stable \

    --network network=default \

    --qemu-commandline="-fw_cfg name=opt/com.coreos/config, file=$IGNITION_CONFIG" \

    --noautoconsole



echo "Fedora CoreOS installed"

จัดการ Container Workloads บน CoreOS

รัน containers ด้วย Podman Quadlet

แนะนำเพิ่มเติม — เรียนเทรดกับ iCafeForex

# === Podman Quadlet (systemd-native containers) ===

# Quadlet = declarative container management ผ่าน systemd



# สร้าง container unit files

# /etc/containers/systemd/nginx.container

cat > /etc/containers/systemd/nginx.container << 'UNIT'

[Unit]

Description=Nginx Web Server

After=network-online.target



[Container]

Image=docker.io/library/nginx:alpine

PublishPort=80:80

PublishPort=443:443

Volume=/opt/data/nginx/html:/usr/share/nginx/html:ro,Z

Volume=/opt/data/nginx/conf:/etc/nginx/conf.d:ro,Z

AutoUpdate=registry

HealthCmd=curl -f http://localhost/ || exit 1

HealthInterval=30s



[Service]

Restart=always

RestartSec=10



[Install]

WantedBy=multi-user.target

UNIT



# สร้าง PostgreSQL container

cat > /etc/containers/systemd/postgres.container << 'UNIT'

[Unit]

Description=PostgreSQL Database

After=network-online.target



[Container]

Image=docker.io/library/postgres:16-alpine

PublishPort=5432:5432

Volume=postgres-data.volume:/var/lib/postgresql/data:Z

Environment=POSTGRES_PASSWORD=secure_password

Environment=POSTGRES_DB=appdb

Environment=POSTGRES_USER=appuser

HealthCmd=pg_isready -U appuser

HealthInterval=30s



[Service]

Restart=always

RestartSec=10



[Install]

WantedBy=multi-user.target

UNIT



# สร้าง Volume

cat > /etc/containers/systemd/postgres-data.volume << 'UNIT'

[Volume]

Driver=local

UNIT



# สร้าง Network

cat > /etc/containers/systemd/app.network << 'UNIT'

[Network]

Subnet=172.20.0.0/16

Gateway=172.20.0.1

UNIT



# Reload และ start

systemctl daemon-reload

systemctl start nginx

systemctl start postgres



# ตรวจสอบ status

systemctl status nginx

systemctl status postgres

podman ps



# === Podman Auto-Update ===

# ตรวจสอบ updates

podman auto-update --dry-run



# Apply updates

podman auto-update



# === Podman Pod (group containers) ===

# สร้าง pod สำหรับ application stack

podman pod create --name app-stack \

    -p 8080:8080 \

    -p 5432:5432



# Add containers to pod

podman run -d --pod app-stack \

    --name app-web \

    -e DATABASE_URL=postgresql://appuser:password@localhost:5432/appdb \

    my-app:latest



podman run -d --pod app-stack \

    --name app-db \

    -e POSTGRES_PASSWORD=password \

    -v pgdata:/var/lib/postgresql/data \

    postgres:16-alpine



# Generate systemd units from pod

podman generate systemd --new --files --name app-stack

sudo mv *.service /etc/systemd/system/

sudo systemctl daemon-reload

sudo systemctl enable --now pod-app-stack



echo "Container workloads configured"

Automatic Updates และ rpm-ostree

Immutable OS Fedora CoreOS Community Building —

จัดการ updates และ package layering

#!/usr/bin/env python3

# fcos_manager.py — Fedora CoreOS Management Tool

import subprocess

import json

import logging

from datetime import datetime



logging.basicConfig(level=logging.INFO)

logger = logging.getLogger("fcos_manager")



class FCOSManager:

    def __init__(self):

        self.deployments = []

    

    def get_status(self):

        result = subprocess.run(

            ["rpm-ostree", "status", "--json"],

            capture_output=True, text=True,

        )

        data = json.loads(result.stdout)

        

        self.deployments = []

        for dep in data.get("deployments", []):

            self.deployments.append({

                "version": dep.get("version", "unknown"),

                "timestamp": dep.get("timestamp", 0),

                "booted": dep.get("booted", False),

                "staged": dep.get("staged", False),

                "checksum": dep.get("checksum", "")[:12],

                "packages_layered": dep.get("requested-packages", []),

                "pinned": dep.get("pinned", False),

            })

        

        return self.deployments

    

    def check_updates(self):

        result = subprocess.run(

            ["rpm-ostree", "upgrade", "--check"],

            capture_output=True, text=True,

        )

        

        if "AvailableUpdate" in result.stdout:

            logger.info("Update available")

            return True

        else:

            logger.info("System is up to date")

            return False

    

    def stage_update(self):

        logger.info("Staging update...")

        result = subprocess.run(

            ["rpm-ostree", "upgrade"],

            capture_output=True, text=True,

        )

        

        if result.returncode == 0:

            logger.info("Update staged. Reboot to apply.")

            return True

        else:

            logger.error(f"Update failed: {result.stderr}")

            return False

    

    def rollback(self):

        logger.info("Rolling back to previous deployment...")

        result = subprocess.run(

            ["rpm-ostree", "rollback"],

            capture_output=True, text=True,

        )

        

        if result.returncode == 0:

            logger.info("Rollback staged. Reboot to apply.")

            return True

        return False

    

    def install_package(self, packages):

        if isinstance(packages, str):

            packages = [packages]

        

        logger.info(f"Layering packages: {packages}")

        cmd = ["rpm-ostree", "install", "--apply-live"] + packages

        result = subprocess.run(cmd, capture_output=True, text=True)

        

        if result.returncode == 0:

            logger.info("Packages layered successfully")

            return True

        else:

            logger.error(f"Failed: {result.stderr}")

            return False

    

    def remove_package(self, packages):

        if isinstance(packages, str):

            packages = [packages]

        

        cmd = ["rpm-ostree", "uninstall"] + packages

        result = subprocess.run(cmd, capture_output=True, text=True)

        return result.returncode == 0

    

    def pin_deployment(self, index=0):

        subprocess.run(

            ["ostree", "admin", "pin", str(index)],

            capture_output=True, text=True,

        )

        logger.info(f"Pinned deployment {index}")

    

    def get_zincati_status(self):

        result = subprocess.run(

            ["systemctl", "status", "zincati", "--no-pager"],

            capture_output=True, text=True,

        )

        

        return {

            "active": "active (running)" in result.stdout,

            "output": result.stdout[:500],

        }

    

    def generate_report(self):

        deployments = self.get_status()

        zincati = self.get_zincati_status()

        

        report = {

            "timestamp": datetime.utcnow().isoformat(),

            "hostname": subprocess.getoutput("hostname"),

            "current_version": next(

                (d["version"] for d in deployments if d["booted"]), "unknown"

            ),

            "deployments": deployments,

            "auto_updates": zincati["active"],

            "containers_running": int(

                subprocess.getoutput("podman ps -q | wc -l")

            ),

        }

        

        return report



# manager = FCOSManager()

# status = manager.get_status()

# for dep in status:

#     marker = " (booted)" if dep["booted"] else ""

#     print(f"  {dep['version']}{marker} [{dep['checksum']}]")

# 

# if manager.check_updates():

#     manager.stage_update()

#

# report = manager.generate_report()

# print(json.dumps(report, indent=2))

สร้าง CoreOS Cluster ด้วย Butane Config

Provision multi-node cluster

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน A/B Testing ML SSL TLS Certificate

#!/bin/bash

# provision_cluster.sh — Provision Fedora CoreOS Cluster

set -euo pipefail



NODES=("node1:10.0.0.11" "node2:10.0.0.12" "node3:10.0.0.13")

SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"

CLUSTER_TOKEN="$(openssl rand -hex 16)"



generate_butane() {

    local hostname=$1

    local ip=$2

    local role=$3

    

    cat << EOF

variant: fcos

version: "1.5.0"

passwd:

  users:

    - name: core

      ssh_authorized_keys:

        - 

      groups: [sudo, docker]



storage:

  files:

    - path: /etc/hostname

      mode: 0644

      contents:

        inline: 

    

    - path: /etc/NetworkManager/system-connections/static.nmconnection

      mode: 0600

      contents:

        inline: |

          [connection]

          id=static

          type=ethernet

          [ipv4]

          method=manual

          addresses=/24

          gateway=10.0.0.1

          dns=8.8.8.8;8.8.4.4

    

    - path: /etc/sysctl.d/99-kubernetes.conf

      mode: 0644

      contents:

        inline: |

          net.bridge.bridge-nf-call-iptables = 1

          net.bridge.bridge-nf-call-ip6tables = 1

          net.ipv4.ip_forward = 1

          vm.max_map_count = 262144

    

    - path: /etc/modules-load.d/kubernetes.conf

      mode: 0644

      contents:

        inline: |

          overlay

          br_netfilter

    

    - path: /opt/cluster/role

      mode: 0644

      contents:

        inline: 

    

    - path: /opt/cluster/token

      mode: 0600

      contents:

        inline: 

    

    - path: /opt/scripts/setup-node.sh

      mode: 0755

      contents:

        inline: |

          #!/bin/bash

          echo "Setting up \$(hostname) as \$(cat /opt/cluster/role)"

          

          # Install k3s

          if [ "\$(cat /opt/cluster/role)" = "controller" ]; then

            curl -sfL https://get.k3s.io | sh -s - server \\

              --token \$(cat /opt/cluster/token) \\

              --tls-san 

          else

            curl -sfL https://get.k3s.io | sh -s - agent \\

              --server https://10.0.0.11:6443 \\

              --token \$(cat /opt/cluster/token)

          fi



    - path: /etc/zincati/config.d/55-updates.toml

      mode: 0644

      contents:

        inline: |

          [updates]

          strategy = "periodic"

          [[updates.periodic.window]]

          days = ["Sun"]

          start_time = "04:00"

          length_minutes = 60



systemd:

  units:

    - name: setup-node.service

      enabled: true

      contents: |

        [Unit]

        Description=Initial node setup

        After=network-online.target

        ConditionPathExists=!/opt/cluster/.setup-done

        [Service]

        Type=oneshot

        ExecStart=/opt/scripts/setup-node.sh

        ExecStartPost=/usr/bin/touch /opt/cluster/.setup-done

        [Install]

        WantedBy=multi-user.target

EOF

}



# Generate configs for each node

echo "=== Generating cluster configs ==="



for node_entry in ""; do

    hostname=""

    ip=""

    

    if [ "$hostname" = "node1" ]; then

        role="controller"

    else

        role="worker"

    fi

    

    echo "Generating config for  () as "

    generate_butane "$hostname" "$ip" "$role" > ".bu"

    butane --pretty --strict ".bu" > ".ign"

    echo "  Created .ign"

done



echo ""

echo "=== Cluster Configuration ==="

echo "Token: "

echo "Controller: node1 (10.0.0.11)"

echo "Workers: node2 (10.0.0.12), node3 (10.0.0.13)"

echo ""

echo "Deploy each node with its .ign file"

echo "After boot, k3s will auto-configure the cluster"

Community Building สำหรับ Open Source Projects

แนวทางสร้าง community สำหรับ open source

# === Open Source Community Building Strategies ===



# 1. Documentation First

# ===================================

# README.md ที่ดีต้องมี:

# - Clear project description (1-2 sentences)

# - Quick start (< 5 minutes to first success)

# - Installation instructions (all platforms)

# - Usage examples with code

# - Contributing guidelines

# - License information

# - Badges (CI status, version, downloads)



# CONTRIBUTING.md template:

# - How to report bugs (issue template)

# - How to suggest features

# - Development setup instructions

# - Code style guidelines

# - Pull request process

# - Code of conduct reference



# 2. Issue Management

# ===================================

# Label system:

# - good-first-issue: สำหรับ newcomers

# - help-wanted: ต้องการความช่วยเหลือ

# - bug: confirmed bugs

# - enhancement: feature requests

# - documentation: docs improvements

# - priority-high/medium/low: prioritization



# Issue templates (.github/ISSUE_TEMPLATE/):

# bug_report.md:

# ---

# name: Bug Report

# about: Report a bug

# labels: bug

# ---

# **Describe the bug**

# **Steps to reproduce**

# **Expected behavior**

# **Environment** (OS, version, etc.)

# **Screenshots/Logs**



# 3. Contributor Experience

# ===================================

# Make first contribution easy:

# - Pre-configured dev container (.devcontainer/)

# - Makefile with common commands

# - CI that runs on PRs automatically

# - Automated code formatting (pre-commit hooks)

# - Clear PR template



# .github/pull_request_template.md:

# ## Description

# ## Type of change

# - [ ] Bug fix

# - [ ] New feature

# - [ ] Breaking change

# - [ ] Documentation update

# ## Testing

# - [ ] Unit tests pass

# - [ ] Manual testing done

# ## Checklist

# - [ ] Code follows project style

# - [ ] Self-review completed

# - [ ] Documentation updated



# 4. Communication Channels

# ===================================

# - GitHub Discussions: Q&A, ideas, show-and-tell

# - Discord/Matrix: real-time chat

# - Blog/Newsletter: project updates

# - Social media: announcements, community highlights

# - Monthly community calls: roadmap, demos



# 5. Recognition

# ===================================

# - All Contributors bot (recognize non-code contributions)

# - Contributor spotlight in release notes

# - Swag for significant contributors

# - Maintainer pathway for active contributors



# 6. Governance

# ===================================

# - Clear decision-making process

# - RFC process for major changes

# - Maintainer guidelines

# - Transparent roadmap

# - Regular releases with changelogs



# 7. Metrics to Track

# ===================================

# - Stars/Forks growth rate

# - Issue response time (target: < 48h)

# - PR review time (target: < 1 week)

# - Contributor count (new per month)

# - Bus factor (knowledge distribution)

# - Time to first contribution



echo "Community building strategies documented"

FAQ คำถามที่พบบ่อย

Q: Immutable OS ติดตั้ง packages เพิ่มได้ไหม?

A: ได้ด้วย rpm-ostree install ซึ่งเรียกว่า package layering จะสร้าง new deployment ที่รวม base OS กับ packages ที่เพิ่ม แต่แนะนำให้ใช้ containers แทนเมื่อเป็นไปได้ เพราะ layered packages ทำให้ update ช้าลงและเพิ่ม complexity ใช้ rpm-ostree สำหรับ system-level tools เท่านั้น เช่น htop, tmux, strace

แนะนำเพิ่มเติม — XM Signal

เนื้อหาเกี่ยวข้อง — อ่านต่อ: Semgrep SAST Monitoring และ Alerting — คู่มือฉบับสมบูรณ์ 2026

Q: Fedora CoreOS กับ Flatcar Container Linux ต่างกันอย่างไร?

A: FCOS ใช้ rpm-ostree package manager อ้างอิง Fedora ecosystem ใช้ Ignition สำหรับ provisioning มี Zincati สำหรับ auto-updates Flatcar ใช้ A/B partition scheme สำหรับ updates ไม่มี package manager (immutable 100%) ใช้ Container Linux Config สำหรับ provisioning FCOS flexible กว่า (layer packages ได้) Flatcar minimal กว่าและ proven ใน production (ex-CoreOS)

Q: ใช้ Immutable OS กับ Kubernetes อย่างไร?

A: เหมาะมากเพราะ Kubernetes nodes ไม่ควรมี state ทั้งหมดอยู่ใน containers FCOS ใช้กับ k3s, k0s หรือ kubeadm ได้ Talos Linux ออกแบบมาเฉพาะสำหรับ Kubernetes nodes (API-managed, no SSH) Bottlerocket ของ AWS ออกแบบสำหรับ EKS nodes auto-updates ทำให้ nodes ได้ security patches อัตโนมัติ

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน Text Generation WebUI Pod Scheduling — จัดการ

Q: จะเริ่มสร้าง open source community อย่างไร?

A: เริ่มจาก documentation ที่ดี (README, CONTRIBUTING, CODE_OF_CONDUCT) สร้าง good-first-issues สำหรับ newcomers ตั้ง communication channels (GitHub Discussions, Discord) respond ทุก issue/PR ภายใน 48 ชั่วโมง recognize contributors ทุกคน (ไม่ใช่แค่ code) เขียน blog posts เกี่ยวกับ project และ share ใน communities ที่เกี่ยวข้อง ความสม่ำเสมอสำคัญกว่า viral moment

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง