buildkit是从Docker从公司开源出来的下一代镜像构建工具,支持OCI标准的镜像构建,项目地址是:https://github.com/moby/buildkit
buildkit由两部分组成:
相对于docker daemon build,buildkit具有以下优势:
下载安装包
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是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仓库
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 #推送镜像测试
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 #推送镜像测试
镜像分层构建示意图:
分层构建可以节约构建镜像的时间和步骤。分层构建是指:
首先构建最底层的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从而构建镜像失败,如下图所示:
这个问题有2个解决办法:
下面以第一种方式为例,通过在系统中添加信任证书解决这个问题:
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
基于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代码的目录
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