Fedora镜像

我采用 Fedora 作为个人开发工作环境,在 macOS工作室kind(本地docker模拟k8s集群) 上运行Fedora容器,以便能够快速构建稳定的工作环境。不管更换什么底层系统( Linux Atlas / Windows Atlas / macOS )都能立即拉起工作环境进行开发。

备注

由于使用 从Dockerfile构建Docker镜像 重复构建镜像时,需要重复在容器内部执行各种软件包安装下载,非常消耗时间。为了能够节约部署时间(特别是局域网内部),我采用在 Docker环境运行Squid ,这样不断重复相同操作系统的安装升级可以节约时间和带宽。

准备工作

由于Docker镜像制作需要反复测试,容器内部OS更新和软件安装会不断重复,所以为了加快进度和节约带宽,采用 Docker客户端的Proxy 配置来加速

最初尝试

我最初想采用 kind 网路部署 Docker环境运行Squid 代理加速

需要注意,所有 docker run 需要加上 --network kind 以便能够不使用默认的 default 网络,而改为使用 kind bridge网络

但是很奇怪, docker build--network 参数和 docker run 不同,不是指定连接的网络,而是指定网络模式:

--network string          Set the networking mode for the RUN instructions during build (default "default")

这给我带来很大困扰,因为当前除了Docker默认的3种网络模式,我在 macOS工作室 使用 kind(本地docker模拟k8s集群) 构建时创建的 kind 网络也是 bridge 类型的:

% docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
6137c2fed5b2   bridge    bridge    local
3536bf002494   host      host      local
ce9eaba7480a   kind      bridge    local
2e726b8a3f97   none      null      local

参考 Exploring Default Docker Networking Part 1 :

  • 容器网络通过 docker network ls 以及 docker network inspect <network_name> 可以检查网络参数,包括 default 指网络参数 "com.docker.network.bridge.default_bridge": "true"

  • 一种方式是采用 Docker环境运行Squid 中思考的方案,在一个容器中插入多个网段网卡,同时为多个网络提供代理;docker注入代理环境变量时采用域名而不是IP,以便bind进容器的 /etc/hosts 能够提供不同的解析

  • 另一种方式是简化docker配置,只部署默认网络的 Docker环境运行Squidkind 网络的代理留给 Kubernetes部署Squid快速起步 来解决(目前我采用这个方法加快部署)

最终执行

  • 我调整了 Docker环境运行Squidkind 网络绑定摘除,恢复构建到Docker default网络的 squid 容器,然后修改 ~/.docker/config.json :

采用默认docker网络 bridge 上部署的 Docker环境运行Squid 代理
{
  "credsStore": "desktop",
  "proxies":
  {
    "default":
    {
      "httpProxy": "http://172.17.0.3:3128",
      "httpsProxy": "http://172.17.0.3:3128",
      "noProxy": "*.baidu.com,192.168.0.0/16,10.0.0.0/8"
    }
  }
}
  • 还有一个问题需要解决: 默认 DNF包管理器 会使用 mirrors.fedoraproject.org 来侦测最快的镜像网站,但是实际上每次选择可能都是不同网站,这导致代理服务缓存效果很差。解决的思路是注释掉 metalink= 行,启用固定的 baseurl= 行 ( How to disable some mirrors for use by dnf in Fedora [closed] 提及原先 yum-plugin-fastestmirror 被移植到dnf时没有移植参数调整功能 )

我采用 sed 修订 /etc/yum.repos.d 目录下配置:

关闭dnf镜像列表功能,指定固定软件仓库以便优化使用proxy代理缓存
REPO_DIR=/etc/yum.repos.d
BACKUP_DIR=/root/yum.repos.d


# backup
cp -R ${REPO_DIR} ${BACKUP_DIR}

cd ${REPO_DIR}/
# download.example/pub/fedora/linux  =>  mirrors.163.com/fedora
rm fedora-cisco-openh264.repo
sed -i 's/metalink=/#metalink=/g' *
sed -i 's/#baseurl=/baseurl=/g' *
sed -i 's/download.example\/pub\/fedora\/linux/mirrors.163.com\/fedora/g' *
cp ${BACKUP_DIR}/fedora-cisco-openh264.repo ${REPO_DIR}/

这里有一个 fedora-cisco-openh264.repo 配置文件没有提供 baseurl= ,实际这个只有一个下载地址,所以跳过替换

下文我将脚本融入 从Dockerfile构建Docker镜像 中执行

基础运行 fedora-base

  • 初始构建一个基础fedora:

基础Fedora镜像Dockerfile
FROM fedora:latest
RUN dnf update

ENTRYPOINT ["/usr/bin/bash"]
  • 构建 fedora-base 镜像:

构建基础Fedora镜像Dockerfile
docker build -t fedora-base .
  • 运行 fedora-base 镜像:

运行fedora-base容器
docker run -dt --name fedora --hostname fedora fedora-base
  • 连接到 fedora 容器内:

通过docker exec运行容器内部bash
docker exec -it fedora /bin/bash
  • 执行 dnf update 可以进一步安装应用软件,可以观察到 Docker环境运行Squid 起到了缓存加速作用,这样后续迭代Dockerfile就节约了时间和带宽

systemd运行ssh fedora-ssh

按照 Docker systemd进程管理器 经验总结,采用以下方法实现Docker容器内通过 Systemd进程管理器 运行ssh,实现一个初始完备的远程可登录 Fedora 系统:

包含systemd和ssh的Fedora镜像Dockerfile
# USE DOCKER BUILD
# docker build --rm -t fedora-ssh .
# USE DOCKER RUN
# docker run -itd --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh

# USE nerdctl (containerd) BUILD
# nerdctl build -t fedora-ssh .

# INTERACT RUN
# nerdctl run -it --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh:latest

# BACKGROUND RUN
# nerdctl run -d --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh:latest

FROM fedora:latest
MAINTAINER vincent huatai <vincent@huatai.me>

ENV container docker

RUN --mount=type=bind,target=/sys/fs/cgroup \
    --mount=type=bind,target=/sys/fs/fuse \
    --mount=type=tmpfs,target=/tmp \
    --mount=type=tmpfs,target=/run \
    --mount=type=tmpfs,target=/run/lock

RUN dnf clean all
RUN dnf -y update

# Fedora docker image not include systemd,install systemd by initscripts
RUN dnf -y install which sudo passwd openssh-clients openssh-server sssd-client initscripts
RUN systemctl enable sshd

# add account "admin" and give sudo privilege
RUN groupadd -g 505 admin
RUN useradd -g 505 -u 505 -d /home/admin -m admin
RUN usermod -aG wheel admin
RUN echo "%wheel        ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers

# set TIMEZONE to Shanghai
RUN unlink /etc/localtime && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# Add ssh public key for login
RUN mkdir -p /home/admin/.ssh
COPY authorized_keys /home/admin/.ssh/authorized_keys
RUN chown -R admin:admin /home/admin/.ssh
RUN chmod 600 /home/admin/.ssh/authorized_keys
RUN chmod 700 /home/admin/.ssh
#RUN mv /var/run/nologin /var/run/nologin.bak

# run service when container started - sshd
EXPOSE 22:1122

# systemd
# CMD ["/usr/sbin/init"]

ENTRYPOINT [ "/usr/lib/systemd/systemd" ]
CMD [ "log-level=info", "unit=sysinit.target" ]
  • 构建 fedora-ssh 镜像:

构建包含systemd和ssh的Fedora镜像
docker build --rm -t fedora-ssh .
  • 运行 fedora-ssh :

运行包含systemd和ssh的Fedora容器
docker run -itd --privileged=true -p 1122:22 \
        --hostname fedora-ssh --name fedora-ssh fedora-ssh

开发环境 fedora-dev

fedora-ssh 基础上,增加开发工具包安装:

  • fedora-dev 包含了安装常用工具和开发环境,并编译和安装必要的vim环境:

包含常用工具和开发环境的Fedora镜像Dockerfile
# USE DOCKER BUILD
# docker build --rm -t fedora-ssh .
# USE DOCKER RUN
# docker run -itd --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh

# USE nerdctl (containerd) BUILD
# nerdctl build -t fedora-ssh .

# INTERACT RUN
# nerdctl run -it --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh:latest

# BACKGROUND RUN
# nerdctl run -d --privileged=true -p 1122:22 --hostname fedora-ssh --name fedora-ssh fedora-ssh:latest

FROM fedora:latest
MAINTAINER vincent huatai <vincent@huatai.me>

ENV container docker

RUN --mount=type=bind,target=/sys/fs/cgroup \
    --mount=type=bind,target=/sys/fs/fuse \
    --mount=type=tmpfs,target=/tmp \
    --mount=type=tmpfs,target=/run \
    --mount=type=tmpfs,target=/run/lock

# set china repo: mirros.163.com
RUN cp -R /etc/yum.repos.d /root/yum.repos.d
RUN rm /etc/yum.repos.d/fedora-cisco-openh264.repo
RUN sed -i 's/metalink=/#metalink=/g' /etc/yum.repos.d/*
RUN sed -i 's/#baseurl=/baseurl=/g' /etc/yum.repos.d/*
RUN sed -i 's/download.example\/pub\/fedora\/linux/mirrors.163.com\/fedora/g' /etc/yum.repos.d/*
RUN cp /root/yum.repos.d/fedora-cisco-openh264.repo /etc/yum.repos.d/

RUN dnf clean all
RUN dnf -y update

# Fedora docker image not include systemd,install systemd by initscripts
RUN dnf -y install which sudo passwd openssh-clients openssh-server sssd-client initscripts \
    vim iproute net-tools bind-utils bzip2 tmux sysstat nfs-utils lsof \
    procps tree file mlocate rsync cronie cronie-anacron \
    git gdb openssl-devel \
    nodejs 

RUN systemctl enable sshd

# add account "admin" and give sudo privilege
RUN groupadd -g 505 admin
RUN useradd -g 505 -u 505 -d /home/admin -m admin
RUN usermod -aG wheel admin
RUN echo "%wheel        ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers

# set TIMEZONE to Shanghai
RUN unlink /etc/localtime && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# Add ssh public key for login
RUN mkdir -p /home/admin/.ssh
COPY authorized_keys /home/admin/.ssh/authorized_keys
RUN chown -R admin:admin /home/admin/.ssh
RUN chmod 600 /home/admin/.ssh/authorized_keys
RUN chmod 700 /home/admin/.ssh
#RUN mv /var/run/nologin /var/run/nologin.bak

# swith to admin set home
USER admin
RUN git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime && sh ~/.vim_runtime/install_awesome_vimrc.sh
RUN python3 -m venv ~/venv3 && source venv3/bin/active
RUN pip install sphinx sphinx_rtd_theme sphinxnotes-strike

# switch back
USER root

# run service when container started - sshd
EXPOSE 22:1122

# systemd
# CMD ["/usr/sbin/init"]

ENTRYPOINT [ "/usr/lib/systemd/systemd" ]
CMD [ "log-level=info", "unit=sysinit.target" ]
fedora-dev 镜像说明

功能

参考

docker容器运行ssh服务

Docker systemd进程管理器

用户目录ssh配置

ssh密钥

fedora开发环境

Fedora

  • 构建 fedora-dev 镜像:

构建包含开发环境的Fedora镜像
docker build --rm -t fedora-dev .
  • 运行 fedora-dev :

运行包含开发环境的Fedora容器
docker run -itd --privileged=true -p 1122:22 \
        --hostname fedora-dev --name fedora-dev fedora-dev