基于nerdctl+buildkit+containerd构建容器镜像

buildkit是从Docker从公司开源出来的下一代镜像构建工具,支持OCI标准的镜像构建,项目地址是:https://github.com/moby/buildkit

buildkit由两部分组成:

  • buildkitd(服务端):负责镜像构建,目前支持runc和containerd作为镜像构建环境,默认是runc
  • buildkitctl(客户端):负责解析Dockerfile文件,并向服务端buildkitd发出构建情趣

相对于docker daemon build,buildkit具有以下优势:

  • 更高效:支持并行的多阶段构建、更好的缓存管理
  • 更安全:支持secret mount,无需root权限
  • 更易于扩展:使用自定义中间语言LLB,完全兼容Dockerfile,也可以支持第三方语言。后台支持runc和containerd

buildktit安装

下载安装包

wget https://github.com/moby/buildkit/releases/download/v0.10.3/buildkit-v0.10.4.linux-amd64.tar.gz
mkdir /tmp/buildkit/
tar xf buildkit-v0.10.4.linux-amd64.tar.gz -C /tmp/buildkit/
mv /tmp/buildkit/bin/* /usr/bin/
rm -rf /tmp/buildkit

准备service文件

cat /lib/systemd/system/buildkit.socket
#######################################
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit

[Socket]
ListenStream=%t/buildkit/buildkitd.sock
SocketMode=0660

[Install]
WantedBy=sockets.target

cat /lib/systemd/system/buildkit.service
#########################################
[Unit]
Description=BuildKit
Requires=buildkit.socket
After=buildkit.socket
Documentation=https://github.com/moby/buildkit

[Service]
ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true

[Install]
WantedBy=multi-user.target

启动服务

systemctl enable buildkit.service
systemctl start buildkit.service

基于nerdctl+buildkit+containerd构建容器镜像_第1张图片

nerdctl 安装使用

nerdctl是containerd的一个客户端命令行工具,使用方式和docker命令基本一致

nerdctl安装

#因为nerdctl运行容器需要使用cni配置容器网络,所以先安装cni
wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
mkdir -p /opt/cni/bin
tar xvf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin/

wget https://github.com/containerd/nerdctl/releases/download/v0.22.0/nerdctl-0.22.0-linux-amd64.tar.gz
tar xvf nerdctl-0.22.0-linux-amd64.tar.gz
cp nerdctl /usr/bin/
nerdctl version

nerdctl命令补全设置

echo "source <(nerdctl completion bash)" >/etc/profile
source /etc/profile

nerdctl访问https仓库

  • 方式1,使用–insecure-registry参数
nerdctl --insecure-registry login harbor-server.linux.io
nerdctl tag ubuntu:20.04 harbor-server.linux.io/base-images/ubuntu:20.04
nerdctl --insecure-registry push harbor-server.linux.io/base-images/ubuntu:20.04	#推送镜像测试
  • 方式2,将harbor证书分发给containerd
mkdir -p /etc/containerd/certs/harbor-server.linux.io/
scp  <harbor-cert-files> <user>@<ip>:/etc/containerd/certs/harbor-server.linux.io/		#根据实际情况修改命令,将harbor证书拷贝到containerd
nerdctl login harbor-server.linux.io
nerdctl push harbor-server.linux.io/base-images/ubuntu:20.04	#推送镜像测试

镜像构建

容器镜像的分层构建

镜像分层构建示意图:
基于nerdctl+buildkit+containerd构建容器镜像_第2张图片
分层构建可以节约构建镜像的时间和步骤。分层构建是指:

  1. 先构建基础镜像,在官方的centos、ubuntu和debian等系统镜像之上安装常用命令,构建完成后基本不用修改可以重复利用
  2. 然后构建运行时环境镜像,在基础镜像之上部署nginx、tomcatl、jdk和spring等业务依赖的运行时环境
  3. 最后构建业务镜像,部署生产业务(根据业务的需求,更改业务镜像即可),构建镜像时只构建业务镜像,花费的时间少,构建镜像的步骤少
构建实践

首先构建最底层的ubuntu镜像

FROM ubuntu:20.04
LABEL author=[email protected]

ADD sources.list /etc/apt/sources.list

RUN apt update && apt -y install iproute2  ntpdate  tcpdump telnet traceroute nfs-kernel-server nfs-common  lrzsz tree  openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute  gcc openssh-server lrzsz tree  openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make && apt clean

执行构建,上传镜像

nerdctl build -t harbor-server.linux.io/base-images/ubuntu:20.04 .
nerdctl push harbor-server.linux.io/base-images/ubuntu:20.04

基于刚才的构建的ubuntu镜像构建一个jdk镜像

#jdk 8 base image
FROM harbor-server.linux.io/base-images/ubuntu:20.04

LABEL author="[email protected]"
ADD jdk-8u131-linux-x64.tar.gz /usr/local/src
RUN ln -s /usr/local/src/jdk1.8.0_131 /usr/local/jdk

ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin


RUN echo "export JAVA_HOME=/usr/local/jdk" >>/etc/profile
RUN echo "export TOMCAT_HOME=/apps/tomcat" >>/etc/profile
RUN echo "export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH" >>/etc/profile
RUN echo "export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar" >> /etc/profile

RUN rm -f /etc/localtime && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

执行构建,上传镜像

nerdctl build -t harbor-server.linux.io/base-images/ubuntu-jdk-base:8u131 .
nerdctl push harbor-server.linux.io/base-images/ubuntu-jdk-base:8u131

PS: 在执行jdk构建的时候遇到一个问题,因为FROM指定的镜像保存在harbor私有仓库中,harbor https配置的是自签的证书,buildkit不认自签的证书,导致无法加载基础镜像的metadata从而构建镜像失败,如下图所示:
基于nerdctl+buildkit+containerd构建容器镜像_第3张图片
这个问题有2个解决办法:

  1. 将自签的根证书加入到系统信任的证书,以ubuntu和centos为例
  2. 修改harbor的部署方式,将harbor改为http,然后将harbor前面的haproxy或nginx代理服务器修改为https,这种方式比较麻烦,这里不展示

下面以第一种方式为例,通过在系统中添加信任证书解决这个问题:
ubuntu:

cp ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
systemctl restart buildkit.service

centos:

cp ca.crt /etc/pki/ca-trust/source/anchors
update-ca-trust extract
systemctl restart buildkit.service

修改完成后再次进行构建就不会报错了,如下图
基于nerdctl+buildkit+containerd构建容器镜像_第4张图片

基于jdk镜像再构建tomcat镜像

#tomcat 8.5.81 base image
FROM harbor-server.linux.io/base-images/ubuntu-jdk-base:8u131

LABEL author="[email protected]"
RUN mkdir -pv /apps /data/tomcat/webapps /data/tomcat/logs
ADD apache-tomcat-8.5.81.tar.gz /apps/
RUN ln -sv /apps/apache-tomcat-8.5.81 /apps/tomcat
RUN useradd -u 2022 tomcat && chown -R tomcat.tomcat /apps /data/tomcat

执行构建上传镜像

nerdctl build -t harbor-server.linux.io/pub-images/tomcat-base:8.5.81 .
nerdctl image push harbor-server.linux.io/pub-images/tomcat-base:8.5.81

基于tomcat镜像构建业务镜像

#tomcat myapp1
FROM harbor-server.linux.io/pub-images/tomcat-base:8.5.81

ADD server.xml /apps/tomcat/conf/
ADD myapp.tar.gz /data/tomcat/webapps/myapp/
ADD run_tomcat.sh /apps/tomcat/bin/
RUN chown -R tomcat.tomcat /apps /data/tomcat
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]

server.xml是tomcat的配置文件修改了存放java代码的目录
基于nerdctl+buildkit+containerd构建容器镜像_第5张图片
myapp.tar.gz里存放的是默认页面index.html,内容可以随便写
run_tomcat.sh是启动tomcat的脚本,内容如下:

su - tomcat -c "/apps/tomcat/bin/catalina.sh run"

执行构建上传镜像

nerdctl build -t harbor-server.linux.io/n70/tomcat-myapp:v1 .
nerdctl image push  harbor-server.linux.io/n70/tomcat-myapp:v1

通过业务镜像启动容器访问测试

nerdctl run -p 8080:8080 -it --rm harbor-server.linux.io/n70/tomcat-myapp:v1

基于nerdctl+buildkit+containerd构建容器镜像_第6张图片
可以成功访问,表示业务镜像构建没问题

你可能感兴趣的:(docker,容器)