Kubernetes集群(z-k8s)使用nerdctl

在完成 Kubernetes集群(z-k8s) 之后,我们需要使用 nerdctl 来完成镜像制作和管理,已经推送镜像到 Kubernetes集群(z-k8s)部署镜像Redgistry 以实现应用部署

buildkit安装和准备

  • 安装 nerdctl (minimal版本,即只安装 nerdctl ):

ARCH=amd64
VER=0.22.2

#命令行下载因转跳失败,所以还是浏览器下载后解压缩
#curl https://github.com/containerd/nerdctl/releases/download/v${VER}/nerdctl-${VER}-linux-${ARCH}.tar.gz -o nerdctl-${VER}-linux-${ARCH}.tar.gz

tar xfz nerdctl-${VER}-linux-${ARCH}.tar.gz
sudo mv nerdctl /usr/bin/
tar xfz buildkit-v0.10.4.linux-amd64.tar.gz
cd bin
sudo mv * /usr/bin/
  • 运行(需要先安装和运行 OCI(runc) 和 containerd):

使用root身份运行buildkitd,启动后工作在前台等待客户端连接
sudo buildkitd
  • 配置 /etc/buildkit/buildkitd.toml :

配置 /etc/buildkit/buildkitd.toml
[worker.oci]
  enabled = false

[worker.containerd]
  enabled = true
  # namespace should be "k8s.io" for Kubernetes (including Rancher Desktop)
  namespace = "default"

然后就可以使用 nerdctl 工具执行 nerdctl build 指令来构建镜像。

使用nerdctl构建镜像

  • 在目录下编辑一个 Dockerfile 内容如下(另外还要准备一个公钥文件 authorized_keys 用于镜像中眠密码登陆):

fedora官方镜像增加systemd,注释中包含启动方法
# 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" ]
  • 执行以下命令构建镜像:

nerdctl build构建支持systemd的Fedora镜像
nerdctl build -t fedora-systemd .
  • 完成后检查镜像:

nerdctl images命令检查刚才生成的支持systemd的Fedora镜像
sudo nerdctl images

可以看到刚才生成的镜像:

nerdctl images命令显示刚才生成的镜像
REPOSITORY                 TAG       IMAGE ID        CREATED         PLATFORM       SIZE         BLOB SIZE
fedora-systemd             latest    c910cbc325a4    31 hours ago    linux/amd64    717.0 MiB    389.2 MiB

使用nerdctl在Kubernetes上运行pod容器

nerdctl 可以直接将镜像推送到 Kubernetes集群(z-k8s) 集群中作为pod运行:

  • 执行 kubectl apply 命令在Kubernetes集群 Kubernetes集群(z-k8s) 中构建运行pod:

  • 准备 z-dev 部署配置 z-dev-depolyment.yaml :

z-dev部署配置z-dev-depolyment.yaml,定义了pod输出的3个服务端口 22,80,443
apiVersion: apps/v1
kind: Deployment
metadata:
  name: z-dev
  labels:
    app: z-dev
    tier: frontend
  namespace: z-dev
spec:
  # replicas: 2
  selector:
    matchLabels:
      app: z-dev
      tier: frontend
  template:
    metadata:
      labels:
        app: z-dev
        tier: frontend
    spec:
      containers:
        - name: z-dev
          image: fedora-systemd
          imagePullPolicy: Never
          securityContext:
            privileged: true
          ports:
          - containerPort: 22
            name: z-dev-ssh
          - containerPort: 80
            name: z-dev-http
          - containerPort: 443
            name: z-dev-https

备注

这里我改进了 nerdctl 中的实践,将 pod 改为 workload resources(工作负载资源) 也就是 Deployment

  • 执行部署:

    kubectl create namespace z-dev
    kubectl apply -f z-dev-depolyment.yaml
    

备注

这里还没有 Kubernetes部署registry仓库 ,所以需要手工将镜像复制到调度的节点来运行期容器

  • 检查当前调度 z-dev 的节点:

    kubectl -n z-dev get pods -o wide
    

可以看到:

NAME                              READY   STATUS     RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
z-dev                             0/2     Init:0/2   0          9s    <none>       z-k8s-n-4   <none>           <none>
  • 需要将镜像导出复制到 z-k8s-n-4 来运行容器:

nerdcrl save保存导出fedora_systemd镜像
sudo nerdctl save fedora-systemd > fedora-systemd.tar
  • 将保存镜像复制到目标主机 z-k8s-n-4

    scp fedora-systemd.tar z-k8s-n-4:/home/huatai/
    
  • z-k8s-n-4 服务器上执行以下命令导入镜像:

nerdcrl load加载fedora_systemd镜像
sudo nerdctl -n k8s.io load < fedora-systemd.tar
  • 完成 z-k8s-n-4 镜像导入后,该节点就能正常运行 fedora-systemd 镜像的pod,此时:

    kubectl -n z-dev get pods -o wide
    

就可以看到容器正常运行:

NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
z-dev                             2/2     Running   0          20m   10.0.7.153   z-k8s-n-4   <none>           <none>

备注

此时,虽然我们可以通过:

kubectl exec -it z-dev -- /bin/bash

登陆到 z-dev 系统内部,但是毕竟不如直接ssh方便,而这个容器已经是 Docker systemd进程管理器 运行了 ssh服务 。所以,此时我们需要完成 Kubernetes集群(z-k8s)部署Cilium Ingress 才能通过外部网络访问 z-dev

参考