Skip to main content

Nichi Yorozuya

Fedora CoreOS

       对于基础设施的管理,往往有两种approach,transactional与declarative。transactional描述动作,比如安装一个软件包,比如向文件中写入一行内容。而declarative描述结果,比如一个软件包已经被安装且满足特定version constraint,或是一个文件中存在某行内容。传统的手工操作是transactional的,负责任的运维可能会记录自己所运行的每一条指令,但是这些指令并不一定幂等,也不一定有对应的rollback方式。现代化的管理工具如ansible或是saltstack多是在transactional的基础上,构建了一个declarative的模型,你可以仅仅描述所期望的状态,依赖管理工具将基础设施推向它

to err is human, to drift is infra

       无论是哪种approach,基础设施往往会慢慢偏移version control中所记录的状态,其原因可能是某次情急之下的hotfix,可能是残留的一个配置文件覆盖了当前的配置,导致reproducible deployment难以实现。为了解决这一现状,我们有一个简单的解决方案:每次配置更新时重装系统,并将文件系统的绝大部分挂载为readonly,这一看似荒诞的方案,确保了version control作为single source of truth的地位。而遵循了这一哲学的,有曾经的CoreOS,和如今的Fedora CoreOS

initialization should be where all changes are done

       Fedora CoreOS所期待的是,在初始化过程完成之后,整个系统便处于一个不变的状态,也即初始化过程需要包含所有的那些原本由管理工具在随后的生命周期中完成的工作,而承担这一任务的即是Ignition。它仅在系统部署完成后的第一次开机时,于initramfs阶段被调用,故而它也可以完成磁盘分区等对于其他管理工具在技术上难以完成的工作。它所使用的配置文件是JSON格式的Ignition configuration file,但是我们需要书写的配置文件是YAML格式的更加对人类友好的FCOS Configuration(即FCC),随后由fcct转译至Ignition,一个示例配置(摘录部分)如下:

variant: fcos
version: 1.0.0
passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - ssh-ed25519 <redacted>
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      contents:
        inline: |
          <redacted>
    - path: /etc/NetworkManager/system-connections/eth0.nmconnection
      mode: 0600
      overwrite: true
      contents:
        inline: |
          [connection]
          type=ethernet
          interface-name=eth0

          [ipv6]
          method=auto
          addr-gen-mode=0
    - path: /etc/sysctl.d/90-network.conf
      mode: 0644
      contents:
        inline: |
          net.ipv4.ip_forward = 1
          net.ipv6.conf.all.forwarding = 1
          net.core.default_qdisc = fq
          net.ipv4.tcp_congestion_control = bbr
    - path: /etc/bird.conf
      mode: 0644
      contents:
        inline: |
          <redacted>
systemd:
  units:
    - name: bird.service
      enabled: true
      contents: |
        [Unit]
        Description=BIRD Internet Routing Daemon
        After=network-online.target
        Wants=network-online.target

        [Service]
        Restart=always
        ExecStartPre=-podman kill bird
        ExecStartPre=-podman rm bird
        ExecStartPre=podman pull quay.io/nickcao/bird
        ExecStart=podman run --name bird --network host -v /etc/bird.conf:/etc/bird.conf quay.io/nickcao/bird

        [Install]
        WantedBy=multi-user.target

       将转译后的JSON作为user-data提供给服务器,或是对于baremetal installation,传递给coreos-installer,Ignition便会在启动之时配置好ssh公钥,hostname,网络地址,并配置和启动bird,无需任何manual intervention或是外部控制器。而在它之后的生命周期中,也不需要配置工具的介入,如果我需要修改bird配置,将会改写FCC,添加到version control,随后开始一次全新的部署。(事实上这一配置摘录自我的一台边界路由,且仅仅只是其中的一小部分,但它仍可在45秒内完成初始化并开始转发数据包)

       如果你想部署一台新的服务器,试试Fedora CoreOS吧

       deploy with confidence