FreeBSDでDockerを動かす場合、いくつかの選択肢がありますが、一番簡単で安定しているBhyveベースでDocker環境を構築します。
前提
- NetBoxでインベントリー管理
- Bhyve管理にvm-bhyve利用
- Docker実行用に軽量なAlpineLinux virt v3.23.4を利用
- AlpineLinuxはあえてgrubブート
AlpineLinux仮想環境構築
roles/freebsd/tasks/vm_bhyve_alpinelinux.yaml
- name: Set AlpineLinux variables
set_fact:
alpinelinux_org: "https://dl-cdn.alpinelinux.org/alpine"
alpinelinux_ver: "3.23"
alpinelinux_ver_rev: "4"
alpinelinux_flavor: "virt"
alpinelinux_kernel: "virt"
alpinelinux_arch: "x86_64"
alpinelinux_host: "docker"
- name: Set ISO
set_fact:
iso: "alpine-{{ alpinelinux_flavor }}-{{ alpinelinux_ver }}.{{ alpinelinux_ver_rev }}-{{ alpinelinux_arch }}.iso"
- name: Check if {{ iso }} exists
stat:
path: "/vm/.iso/{{ iso }}"
register: iso_file
- name: Get AlpineLinux ISO
command: |
vm iso {{ alpinelinux_org }}/v{{ alpinelinux_ver }}/releases/{{ alpinelinux_arch }}/{{ iso }}
register: result
when:
- not iso_file.stat.exists
- vm_bhyve_installed
changed_when: false
- name: Check if {{ alpinelinux_host }}.conf exists
stat:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
register: conf_file
- name: Check if template file exists
stat:
path: /vm/.templates/alpine.conf
register: alpine_conf_file
- name: Check if template file exists
stat:
path: /vm/.templates/legacy-alpine.conf
register: legacy_alpine_conf_file
- name: Create {{ alpinelinux_host }}
command: |
vm create -t alpine -c 2 -m 2G -s 20G {{ alpinelinux_host }}
register: result
when:
- alpine_conf_file.stat.exists
- not conf_file.stat.exists
- vm_bhyve_installed
changed_when: false
- name: Create {{ alpinelinux_host }}
command: |
vm create -t legacy-alpine -c 2 -m 2G -s 20G {{ alpinelinux_host }}
register: result
when:
- legacy_alpine_conf_file.stat.exists
- not conf_file.stat.exists
- vm_bhyve_installed
changed_when: false
- name: Fix grub_install0
lineinfile:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
regexp: '^grub_install0="linux /boot/vmlinuz-vanilla initrd=/boot/initramfs-vanilla alpine_dev=cdrom:iso9660 modules
=loop,squashfs,sd-mod,usb-storage,sr-mod"$'
line: 'grub_install0="linux /boot/vmlinuz-{{ alpinelinux_kernel }} initrd=/boot/initramfs-{{ alpinelinux_kernel }} a
lpine_dev=cdrom:iso9660 modules=loop,squashfs,sd-mod,usb-storage,sr-mod"'
when:
- vm_bhyve_installed
- name: Fix grub_install1
lineinfile:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
regexp: '^grub_install1="initrd /boot/initramfs-vanilla"$'
line: 'grub_install1="initrd /boot/initramfs-{{ alpinelinux_kernel }}"'
when:
- vm_bhyve_installed
- name: Fix grub_run0
lineinfile:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
regexp: '^grub_run0="linux /boot/vmlinuz-vanilla root=/dev/vda3 modules=ext4"$'
line: 'grub_run0="linux /boot/vmlinuz-{{ alpinelinux_kernel }} root=/dev/vda3 modules=ext4"'
when:
- vm_bhyve_installed
- name: Fix grub_run1
lineinfile:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
regexp: '^grub_run1="initrd /boot/initramfs-vanilla"$'
line: 'grub_run1="initrd /boot/initramfs-{{ alpinelinux_kernel }}"'
when:
- vm_bhyve_installed
- name: Update {{ alpinelinux_host }} configuration
blockinfile:
path: "/vm/{{ alpinelinux_host }}/{{ alpinelinux_host }}.conf"
block: |
disk1_type="ahci-cd"
disk1_dev="custom"
disk1_name="/vm/.iso/{{ iso }}"
when:
- vm_bhyve_installed
- name: Check if {{ iso }} exists
stat:
path: "/vm/.iso/{{ iso }}"
register: iso_file
- name: Install {{ alpinelinux_host }}
command: |
vm install {{ alpinelinux_host }} {{ iso }}
register: result
when:
- iso_file.stat.exists
- vm_bhyve_installed
changed_when: false
- name: vm_list
community.general.sysrc:
name: vm_list
value: "{{ alpinelinux_host }}"
when:
- vm_bhyve_installed
インストール
コンソールログイン
vm console docker login: root
インストールスクリプト作成
Bhyveのgrubがext4のブート領域からカーネルをブートできないので、setup-alpine実行後にext2でブート領域を再作成します。
/setup.sh
#!/bin/sh
setup-alpine
mount /dev/vda3 /mnt
mount /dev/vda1 /mnt/boot
mkdir -p /tmp/boot
cp -pr /mnt/boot/* /tmp/boot/
umount /mnt/boot
mkfs.ext2 -O ^64bit /dev/vda1
mount -t ext2 /dev/vda1 /mnt/boot
cp -pr /tmp/boot/* /mnt/boot/
umount /mnt/boot
NEW_UUID=`blkid -s UUID -o value /dev/vda1`
cp -p /mnt/etc/fstab /mnt/etc/fstab.orig
sed -i "/\/boot/c\UUID=${NEW_UUID}\t\/boot\text2\trw,relatime\t0 2" /mnt/etc/fstab
umount /mnt
reboot
実行
/setup.sh
Docker
Ansibleの有効化
ssh -l root docker login: root password: XXXXXXXXXXXXXXXXXXX apk add python3 apk add sshpass mkdir -p /root/.ssh chmod 700 /root/.ssh cat > /root/.ssh/authorized_keys 鍵をペースト ^D
Dockerの有効化
roles/alpinelinux/tasks/docker.yaml
- name: Update repo
lineinfile:
path: /etc/apk/repositories
regexp: '^#http://dl-cdn.alpinelinux.org/alpine/v{{ alpinelinux_ver }}/community$'
line: http://dl-cdn.alpinelinux.org/alpine/v{{ alpinelinux_ver }}/community
- name: Update repo
blockinfile:
path: /etc/apk/repositories
block: |
http://dl-cdn.alpinelinux.org/alpine/edge/main
http://dl-cdn.alpinelinux.org/alpine/edge/community
http://dl-cdn.alpinelinux.org/alpine/edge/testing
- name: Ensure /etc/docker directory installed
file:
path: /etc/docker
state: directory
mode: "0755"
- name: /etc/docker/daemon.json
copy:
dest: /etc/docker/daemon.json
content: |
{
"firewall-backend": "nftables"
}
- name: apk add
command: apk add docker docker-compose
register: result
- name: Add net.ipv4.ip_forward=1
lineinfile:
path: /etc/sysctl.conf
regexp: '^net.ipv4.ip_forward='
line: net.ipv4.ip_forward=1
- name: Reload sysctl
command: sysctl -p
- name: Start docker
service:
name: docker
state: started
- name: update docker
command: rc-update add docker boot
ローカル docker run 実行テスト
docker run --rm hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
リモート docker 実行スクリプト
docker.sh
#!/bin/sh DOCKER_HOST="docker" DOCKER_ARGS="$*" ssh -l root $DOCKER_HOST "docker $DOCKER_ARGS"