Fedora镜像(采用tini替代systemd)¶
虽然我构建的 Fedora镜像 (使用systemd作为init进程管理器)能够完美在Docker中运行,但是迁移到 Kubernetes Atlas 中运行( kind部署 fedora-dev )却无法正确初始化 Systemd进程管理器 。我尝试采用Docker默认的init管理器 Docker tini进程管理器 来再次尝试构建镜像,以期能够在 kind部署 fedora-dev-tini (tini替代systmed)
备注
由于使用 从Dockerfile构建Docker镜像 重复构建镜像时,需要重复在容器内部执行各种软件包安装下载,非常消耗时间。为了能够节约部署时间(特别是局域网内部),我采用在 Kubernetes部署Squid 在我的 kind(本地docker模拟k8s集群) ( macOS工作室 ) ,这样不断重复相同操作系统的安装升级可以节约时间和带宽。
准备工作¶
由于Docker镜像制作需要反复测试,容器内部OS更新和软件安装会不断重复,所以为了加快进度和节约带宽,采用 Docker客户端的Proxy 配置来加速: (注意:这里首先需要在docker集群中部署 Docker环境运行Squid 代理容器,然后通过 Docker客户端的Proxy 配置为所有docker容器注入使用代理服务器访问外网来加速下载)
修改
~/.docker/config.json
:
{
"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
目录下配置:
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-tini
¶
初始构建一个基础fedora:
FROM fedora:latest
# 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
ENTRYPOINT ["/usr/bin/bash"]
构建
fedora-base-tini
镜像:
docker build -t fedora-base-tini .
运行
fedora-base-tini
镜像:
docker run -dt --name fedora-base-tini --hostname fedora-base-tini fedora-base-tini
连接到
fedora-base-tini
容器内:
docker exec -it fedora-base-tini /bin/bash
tini运行ssh fedora-ssh-tini
¶
备注
How to enable SSH connections into a Kubernetes pod 提供了一个更好的部署SSH key的 使用ConfigMap配置Pod 方法,适合对不同用户在部署pods时候注入SSH key和构建用户HOME目录,后续借鉴实践。
按照 Docker tini进程管理器 经验总结,采用以下方法实现Docker容器内通过 Systemd进程管理器 运行ssh,实现一个初始完备的远程可登录 Fedora 系统:
fedora-ssh-tini
包含了安装 Docker tini进程管理器 以及 ssh服务 服务,并构建基于认证的SSH登陆环境:
# USE DOCKER BUILD
# docker build --rm -t fedora-ssh-tini .
# USE DOCKER RUN
# docker run -itd --privileged=true -p 1122:22 --hostname fedora-ssh-tini --name fedora-ssh-tini fedora-ssh-tini
# USE nerdctl (containerd) BUILD
# nerdctl build -t fedora-ssh-tini .
# INTERACT RUN
# nerdctl run -it --privileged=true -p 1122:22 --hostname fedora-ssh-tini --name fedora-ssh-tini fedora-ssh-tini:latest
# BACKGROUND RUN
# nerdctl run -d --privileged=true -p 1122:22 --hostname fedora-ssh-tini --name fedora-ssh-tini fedora-ssh-tini:latest
FROM fedora:latest
MAINTAINER vincent huatai <vincent@huatai.me>
ENV container docker
# 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
# Add Tini
ENV TINI_VERSION v0.19.0
# 标准方法是采用ADD方式向镜像添加tini,但是GFW阻碍,改为下载后本地复制
#ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
COPY tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
# Copy tini entrypoint script
COPY entrypoint_ssh_cron_bash /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Fedora docker image not include systemd,install systemd by initscripts
RUN dnf -y install which sudo passwd openssh-clients openssh-server
# 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 ssh-keygen -A
# run service when container started - sshd
EXPOSE 22:1122
# Run your program under Tini
# CMD ["/your/program", "-and", "-its", "arguments"]
CMD ["/entrypoint.sh"]
其中,使用的 entrypoint.sh
脚本是 kind部署 fedora-dev-tini (tini替代systmed) 实践中改进过的脚本:
/entrypoint.sh
脚本的 main()
确保持续运行(循环)¶#!/usr/bin/env bash
sshd() {
/usr/sbin/sshd
}
crond() {
/usr/sbin/crond
}
main() {
sshd
crond
# 在k8s不能直接bash执行结束,否则判断为pod Crash,需要改写成持续执行循环脚本
#/bin/bash
/bin/bash -c "while true; do (echo 'Hello from tini'; date; sleep 120); done"
}
main
构建
fedora-ssh-tini
镜像:
docker build --rm -t fedora-ssh-tini .
运行
fedora-ssh-tini
:
docker run -itd -p 1122:22 \
--hostname fedora-ssh-tini --name fedora-ssh-tini fedora-ssh-tini
开发环境 fedora-dev-tini
¶
在 fedora-ssh-tini
基础上,增加开发工具包安装:
fedora-dev-tini
包含了安装常用工具和开发环境,并编译和安装必要的vim环境:
# USE DOCKER BUILD
# docker build --rm -t fedora-dev-tini .
# USE DOCKER RUN
# docker run -itd --privileged=true -p 1122:22 --hostname fedora-dev-tini --name fedora-dev-tini fedora-dev-tini
# USE nerdctl (containerd) BUILD
# nerdctl build -t fedora-dev-tini .
# INTERACT RUN
# nerdctl run -it --privileged=true -p 1122:22 --hostname fedora-dev-tini --name fedora-dev-tini fedora-dev-tini:latest
# BACKGROUND RUN
# nerdctl run -d --privileged=true -p 1122:22 --hostname fedora-dev-tini --name fedora-dev-tini fedora-dev-tini:latest
FROM fedora:latest
MAINTAINER vincent huatai <vincent@huatai.me>
ENV container docker
# 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
# Add Tini
ENV TINI_VERSION v0.19.0
# 标准方法是采用ADD方式向镜像添加tini,但是GFW阻碍,改为下载后本地复制
#ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
COPY tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
# Copy tini entrypoint script
COPY entrypoint_ssh_cron_bash /entrypoint.sh
RUN chmod +x /entrypoint.sh
# not need systemd(initscripts)
RUN dnf -y install which sudo passwd openssh-clients openssh-server \
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
# 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 ssh-keygen -A
# run service when container started - sshd
EXPOSE 22:1122
# Run your program under Tini
# CMD ["/your/program", "-and", "-its", "arguments"]
CMD ["/entrypoint.sh"]
功能 |
参考 |
---|---|
docker容器运行ssh服务 |
|
用户目录ssh配置 |
|
fedora开发环境 |
构建
fedora-dev-tini
镜像:
docker build --rm -t fedora-dev-tini .
运行
fedora-dev-tini
:
docker run -itd -p 1122:22 \
--hostname fedora-dev-tini --name fedora-dev-tini fedora-dev-tini
修正
: 真正能够用于Kubernetes的Dockerfile¶
警告
在 kind部署 fedora-dev-tini (tini替代systmed) 实践中发现,上述 fedora-dev-tini
和 fedora-ssh-tini
都会 Crash
,原因是 /entrypoint.sh
脚本直接运行结束,会被 Kubernetes 判断为程序 Crash 。所以,实际 /entrypoint.sh
需要改写成最后执行的 bash
命令永不结束!!!