Hero Image
DIUN-容器镜像更新通知

我们通常可以将一台或多台服务器作为Docker主机,使用容器跑一些开源的工具服务。而往往我们不知道该什么时候这个这些应用有了更新的版本,最近发现了一个开源的工具,可以检查主机上运行的容器的镜像是否有更新,并可以通过集成多种渠道发送更新通知,这款工具就是 DIUN(Docker Image Update Notifier) 。 DUIN介绍 DUIN是一款使用GO语言编写的命令行工具,可以本地运行,也可以通过容器运行(开发者提供了构建好的镜像 ),当监控的容器镜像在相应的注册表(Registry)中更新时,可以接收到相应的通知。 DUIN支持多种监控配置(Providers): Docker - 分析Docker主机上运行容器的镜像,并检查其更新 Podman - 类似Docker,需要Podman以服务方式启动 Kubernetes - 分析Kubernetes集群中的Pods,检查pod使用的镜像 Swarm - 分析Swarm集群中服务使用的镜像 Nomad - 类似Docker,分析Nomad引擎运行的镜像 Dockerfile - 分析Dockerfile中引用的镜像 File - yaml格式的配置文件,直接配置需要检查的镜像信息 DUIN支持集成多种通知渠道,例如 Discord, Slack,Matrix,Telegram 以及 Webhook 等。 DUIN使用示例 这里将演示在Docker主机上使用Docker Compose来运行duin服务,并集成Slack,将通知发送到相应的频道。 docker-compose.yml : services: diun: image: crazymax/diun:latest container_name: diun hostname: home200-diun command: serve volumes: - diundata:/data - "/var/run/docker.sock:/var/run/docker.sock" environment: - "TZ=Asia/Shanghai" - "LOG_LEVEL=info" - "LOG_JSON=false" - "DIUN_WATCH_WORKERS=20" - "DIUN_WATCH_SCHEDULE=0 */6 * * *" - "DIUN_WATCH_JITTER=30s" - "DIUN_PROVIDERS_DOCKER=true" - "DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=true" - "DIUN_NOTIF_SLACK_WEBHOOKURL=https://hooks.

Hero Image
最小化静态WEB容器实践

在现代的B/S架构应用中,我们会做前后端分离,某些前端Web服务会将编译完成的静态文件放到一个web服务器进行部署。例如,我的博客也是基于Hugo编译的静态文件来进行部署的。 那在容器化部署模式下,我们需要基于一个web服务的基础容器(镜像)将静态文件构建成站点或者Web服务的容器镜像来进行部署。在Docker开发最佳实践中,我们应该尽量保持镜像足够小(Size大小)。因此,我们应该尽量选择满足我们需求的web服务基础镜像足够小。 大部分情况下,我们会选择Nginx作为我们的web服务器,一开始我也是这么选择的,因为社区在Docker Hub上为我们提供了开箱即用的容器镜像,下面来看看我用来构建静态web服务的过程。 Nginx On Alpine 我们知道在容器构建的实践中,我们可以选择基于AlpineLinux为分发系统的镜像,其比其他(例如 ubuntu, centos等)的镜像会小很多。因此一开始我们也是选择基于Alpine的nginx镜像,例如 nginx:1.22-alpine。 $ docker image pull nginx:1.22-alpine $ docker image ls | grep nginx nginx 1.22-alpine 23.5MB 可以看到其大小为 23.5MB 。 基于该惊醒构建我的博客的发布镜像 FROM mengzyou/hugo:0.106 AS builder COPY --chown=hugo:hugo . /home/hugo/app RUN hugo FROM nginx:1.22-alpine COPY --from=builder /home/hugo/app/public/ /usr/share/nginx/html $ docker build -t myblog:nginx . $ docker image ls --format "{{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep myblog myblog nginx 29MB 构建出来而最终交付镜像的大小为 29MB 。 Easyhttpd On Alpine 后来,我发现了一个用GoLang编写的轻量级web服务器 - easyhttpd,于是我Fork了该项目,编写了一个Dockerfile来构建该web服务器的镜像,具体可查看该文件内容。

Hero Image
轻量级Kubernetes集群-K3S

K3S 是 Rancher 为物联网(IoT)和边缘计算环境开发的轻量级 Kubernetes 发行版本。相比原生的 Kubernetes,其移除了很多非必要的组件,例如云控制管理器(CCM)、内置的(In-Tree)的存储插件等,以及为ARM架构的基础设施做了优化。 K3s 的轻量级同时也体现在其打包成一个二进制可执行文件进行分发,状态存储除了支持 etcd 外,还支持 Sqlite3、MySQl和Postgres。其跟多特性可参考官方文档。 K3s 支持单节集群部署(可用于开发测试环境),也支持高可用的多节点集群。同时还可以通过 k3d 项目快速在本地开发环境使用Docker容器部署 k3s 集群作为开发环境。 这里我将演示通过虚拟机部署一个高可用的多节点集群(3个Servers节点 + 3个Agent节点)。 k3S架构 上图是来自k3s官网的架构图,其架构与Kubernetes的架构是相似的,k3s的server节点也就是控制面节点,agent节点是工作负载节点。k3s默认使用 containerd 作为容器运行时。 更信息的部署架构可参考官方文档。 准备虚拟机节点 这里我们将部署 3 + 3 的集群,需要6台虚拟机,基本配置如下 主机名 IP vCPU 内存 homek3s-server1 192.168.0.150 1 2 GB homek3s-server2 192.168.0.151 1 2 GB homek3s-server3 192.168.0.152 1 2 GB homek3s-agent1 192.168.0.154 2 4 GB homek3s-agent2 192.168.0.155 2 4 GB homek3s-agent3 192.168.0.156 2 4 GB 部署的最小需求,可参考官方文档。 K3s 支持大部分主流的Linux操作系统,这里我使用的是 openSUSE Leap Micro 15.

Hero Image
开始使用DOCKER COMPOSE V2

Compose V2 项目启动于2021年6月,直到2022年4月26号,发布了GA版本。在发布GA版本后,社区也宣布对于Compose V1将不会再进行功能更新,将在6个月后结束生命周期(EOL),期间会进行关键的安全和错误修复。 V1与V2的兼容对比 确保 V1 和 V2 之间的兼容性对于日常工作流程至关重要,下面是V2中两个关键的更改 更改 潜在影响 迁移 V2原生支持BuildKit,并且默认开启 开发者在V2中将默认使用BuildKit进行镜像构建 可通过设置环境变量不使用 DOCKER_BUILDKIT=0 容器名字中使用 - 替代了 _ 作为分隔符 如果在脚本中使用了容器名字,这可能会导致错误 可以通过 “–compatibility” 标记来关闭此更改 关于更多的兼容性更改,请查看兼容性文档 如何安装Compose V2 Windows,MacOS和Linux上使用Docker Desktop,就自带了Compose V2,可通过命令 docker compose 执行。也可以通过配置“Use Docker Compose V2“来设置 docker-compose 别名到 docker compose。 如果没有使用Docker Desktop for Linux,而是直接使用的Docker Engine,则需要额外安装 docker-compose-plugin 或者独立的二进制包。 例如对于Ubuntu,可以通过Docker官方的APT源直接安装 ❯ sudo apt update ❯ sudo apt install docker-compose-plugin 其他Linux, 例如在我的 openSUSE 上,通过手动从Github下载二进制文件进行安装(注意选择版本和平台架构) ❯ DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} ❯ mkdir -p $DOCKER_CONFIG/cli-plugins ❯ wget https://github.

Hero Image
升级OPENSUSE LEAP

openSUSE Leap 15.2自2022年1月4日起已结束生命周(EOL),还在使用该系统的用户未来将不会再收到任何形式的安全与维护更新。 建议所有用户尽快将系统升级到 - openSUSE Leap 15.3,该系统将获得安全补丁和更新直至2022年11月。下一个版本openSUSE Leap 15.4也将预计在2022年6月发布。 喜欢滚动更新版的的朋友,也可以借此机会从Leap版本切换到Tumbleweed版本。 openSUSE Leap的版本升级可以通过联网在线升级,也可以通过下载最新版本的ISO文件进行线下升级,这里面我们将看看如何在线升级。 openSUSE Leap在线升级 使用在线升级的方式有如下优势: 只需要下载需要更新的软件包,将节省不少带宽 在升级期间,虽然不推荐,但是你任然可以使用系统,只有在升级完成后需要重新启动 因为不需要下载ISO镜像文件,所以不需要DVD驱动器或者刻录USB启动盘,需要的仅仅是网络 当然在线升级也有如下缺点: 如果由于某些原因,导致升级过程被中断(例如突然断电,网络连接断开),升级进程无法继续,这有可能会留下一个被破坏的系统 如果有多个系统需要升级,那么下载ISO镜像可能会更省带宽 注意,如果你使用的是更旧的Leap版本,例如 15.1,请先升级到15.2之后,再升级到15.3 。 你可以使用如下命令查看当前版本 > lsb_release -d Description: openSUSE Leap 15.2 虽然正常的升级不会导致用户数据的丢失,但是为了安全,建议在升级之前备份自己重要的个人数据。 升级系统之前的准备 首先检查更新源是否存在并更新当前发行版本的软件包 # zypper repos --uri ... 29 | repo-update | 主更新源 | Yes | ( ) No | No | https://mirrors.tuna.tsinghua.edu.cn/opensuse/update/leap/15.2/oss/ 30 | repo-update-non-oss | 主更新源(非开源软件) | Yes | ( ) No | No | https://mirrors.

Hero Image
DOCKER LIVERESTORE特性

我们都知道Docker是C/S模式架构,通过客户端(CLI)访问Docker Daemon来创建和管理容器的。在默认情况下,当daemon终止的时候,会停止所有运行的容器。 因此我们需要对Docker Daemon进行升级或者某些需要重启的维护操作时,都需要导致运行着的容器跟着重新启动。 Live Restore 其实,Docker提供了一个特性,可以使得在Daemon不可用的时候,保持容器继续运行,这样就减少了在Daemon进行升级或者出现问题的时候容器的停机时间。那这个特性就叫做Live Restore 。 通过为Docker Daemon增加以下配置来开启Live Restore特性。在Linux上,默认的配置文件 /etc/docker/daemon.json 里添加 { "live-restore": true } 然后重启docker服务。如果使用systemd管理服务,可以通过reload来避免重启docker服务 sudo systemctl reload docker.service 其他情况下,可以发送 SIGHUP 信号给dockerd进程。 对于Windows和MacOS上的Docker Desktop,可以通过Desktop节目的Daemon高级配置来开启Live Restore。 配置完成后,可以尝试重启Docker Daemon来查看容器是否会保持继续运行。重启之前查看容器的启动时间  WSL -   mengz  docker container inspect portainer_edge_agent -f '{{ .State.StartedAt }}' 2021-12-18T09:50:59.761725785Z 然后执行 sudo systemctl restart docker.service,在查询一次容器的启动时间,将发现启动时间未发生变化,这说明了容器并没有重启。 Live Restore的限制 当前的Live Restore特性可以在进行Daemon维护,或者在Daemon发生问题导致不可用的情况,减少容器的停机时间,不过其也有一定的限制。 Docker版本升级限制 Live Restore仅支持Docker补丁版本升级时可用,也就是 YY.MM.x 最后一位发生变化的升级,而不支持大版本的升级。在进行大版本升级后,可能会导致Daemon无法重新连接到运行中容器的问题,这时候需要手动停止运行的容器。 Daemon选项变更 也就是说Live Restore仅仅在某些Daemon级别的配置选项不发生改变的情况工作,例如Bridge的IP地址,存储驱动类型等。如果在重启Daemon时候,这些选项发生了改变,则可能会到Daemon无法重新连接运行中的容器,这时也需要手动停止这些容器。 影响容器的日志输出 如果Daemon长时间停止,会影响运行容器的日志输出。因为默认情况下,日志管道的缓冲区大小为64k,当缓冲写满之后,必须启动Daemon来刷新缓冲区。 不支持Docker Swarm Live Restore只是独立Docker引擎的特性,而Swarm的服务是由Swarm管理器管理的。当Swarm管理器不可用时,Swarm服务是可以在工作节点上继续运行的,只是不同通过Swarm管理器进行管理,直到Swarm管理恢复工作。

Hero Image
SYSTEMD定时服务

我上一篇文章中介绍的locate文件查找命令,需要依赖updatedb更新索引才能快速查找文件,因此需要定时运行该命令来更新文件索引。我们知道在Linux和类Unix系统上通常使用crontab来创建定时任务。 在Ubuntu上我们使用apt install mlocate之后,会安装一个脚本文件到 /etc/cron.daily/mlocate,也就是通过Cron机制来每天执行updatedb。然而在我的openSUSE上却并未发现有相关的Crontab配置,但我发现索引文件还是在每天的零点进行了更新,那这个定时任务是谁来执行的呢? 我通过查找与mlocate相关的文件,发现了以下几个文件: ❯ locate "mlocate" /etc/systemd/system/timers.target.wants/mlocate.timer /usr/lib/systemd/system/mlocate.service /usr/lib/systemd/system/mlocate.timer 原来在openSUSE系统上,使用的是Systemd的定时单元来实现的。Systemd是一种Linux系统服务管理程序,在我之前的文章在OPENSUSE上使用SYSTEMCTL管理系统服务中介绍过。 那这里我们将重点介绍下Systemd的定时服务(systemd timer unit)。 systemd定时单元 类似与Cron,systemd的定时单元在Linux系统上提供了机制来调度任务,相比于Cron机制,其他具有以下特性(在使用systemd作为初始化和服务管理的系统上): 调度的任务可以依赖于其他systemd服务 可以使用systemctl命令来管理定时单元,类似与管理systemd服务 除了类似Cron的循环实时定时任务(realtime)之外,还支持一种基于非时间事件触发的任务(monotonic) 定时单元记录日志到systemd的日志系统(journal),因此方便于统一监控和诊断 systemd定时任务的类型 上面的特性中,我们提到其支持两种类型 - realtime 和 monotonic Realtime - 类似于Cron,这种类型的定时任务由定义的绝对时间来触发,在配置文件中通过 OnCalendar 选项来定义 Monotonic - 这种类型的定时任务将会在指定的事件(例如系统启动,服务激活)一定时间后触发,在配置文件中通过 OnBootSec 和 OnUnitActiveSec ,OnStartupSec 等选项来定义,并且该类型的定时任务触发时间不是固定的,在每一次系统重启之后都会被重置 systemd定时任务的配置 在文章开始,我们在寻找mlocate更新文件索引的定时任务时看到,有文件 /usr/lib/systemd/system/mlocate.timer ,没错,就是通过以 .timer 作为扩展名的systemd单元文件来定义systemd的定时单元的 [Unit] Description=Daily locate database update Documentation=man:updatedb [Timer] OnCalendar=daily AccuracySec=12h Unit=mlocate.service Persistent=true [Install] WantedBy=timers.target 可以看到文件格式与systemd服务的单元文件类似,不过需要 [Timer] 段,在该段定义了如下选项 OnCalendar=daily,意思是每天触发 AccuracySec=12h,意思是由于某些原因需要推测执行的时间 Unit=mlocate.service,这里就是指定了需要执行的任务服务 Persistent=true,指定如果由于关机等原因到时了为能执行任务的情况下,启动会立即触发该任务 那该定时单元指定了 mlocate.service 作为触发执行的任务,也就是 /usr/lib/systemd/system/mlocate.

Hero Image
文件系统查找工具

众所周知,在Linux或者类Unix的文件系统中,想通过文件名关键字查找文件,可以通过find命令。那本文将推荐2款可以快速查找文件的工具,性能比find命令更好,可在某些场景下替换find的使用。 mlocate 大部分的Linux发行版的都提供了 mlocate 软件包,该软件包包含了一个locate命令用于查找文件,和一个updatedb命令用于更新文件索引供locate使用。 可直接通过系统的软件包管理工具直接安装 # CentOS/RHEL $ sudo dnf install mlocate # Debian/Ubuntu $ sudo apt install mlocate 安装完成后,首先需要执行以下命令进行文件索引 sudo updatedb 索引文件将默认存放在 /var/lib/mlocate/mlocatedb ,也可以修改配置文件 /etc/updatedb.conf 文件,添加某些不需要索引的文件夹,例如 # Paths which are pruned from updatedb database PRUNEPATHS="/tmp /var/tmp /var/cache /var/lock /var/run /var/spool /mnt /cdrom /usr/tmp /proc /media /sys /.snapshots /var/run/media" 完成索引之后,就可以使用 locate 命令进行文件查找了,例如 $ locate mlocate /etc/systemd/system/timers.target.wants/mlocate.timer /usr/bin/rpmlocate /usr/lib/systemd/system/mlocate.service /usr/lib/systemd/system/mlocate.timer /usr/sbin/rcmlocate /usr/share/doc/packages/mlocate /usr/share/doc/packages/mlocate/AUTHORS /usr/share/doc/packages/mlocate/ChangeLog /usr/share/doc/packages/mlocate/NEWS /usr/share/doc/packages/mlocate/README /usr/share/licenses/mlocate /usr/share/licenses/mlocate/COPYING /usr/share/man/man5/mlocate.db.5.gz /var/lib/mlocate /var/lib/mlocate/mlocate.