关于Kubernetes(k8s)从使用Docker到切换为使用Containerd的相关:
早期Kubernetes与Docker的配合使用
- 在早期的Kubernetes版本中,Docker是非常常用的容器运行时选择。Docker作为一款流行的容器引擎,提供了便捷的容器创建、管理以及镜像操作等功能。当与Kubernetes配合时,Kubernetes通过一个名为dockershim的组件来和Docker进行集成。
- dockershim起到了一个桥梁的作用,它使得Kubernetes的kubelet(Kubernetes中每个节点上负责管理容器的组件)能够与Docker进行通信,从而实现诸如创建Pod(Kubernetes中最小的可部署单元,一个Pod可以包含一个或多个容器)时利用Docker来启动容器、获取容器状态、管理容器生命周期等操作。例如,当用户在Kubernetes集群中部署一个应用,通过定义Pod的配置文件,kubelet会借助dockershim通知Docker按照配置要求启动相应的容器来运行应用程序。
转变为使用Containerd
- 背景与原因:随着容器技术生态的发展,人们对容器运行时的需求也在发生变化。Containerd作为一个从Docker项目中剥离出来的专注于容器运行时管理的开源项目,具有一些优势,比如它更加轻量化、对底层资源的管理更加精细高效等。同时,为了让Kubernetes在容器运行时方面有更通用、更符合云原生发展趋势的选择,从Kubernetes 1.7版本开始,Containerd就能够直接与Kubelet集成使用,但在那时候大部分用户因熟悉Docker,在部署集群时还是采用了默认的dockershim。
- 版本切换节点:在Kubernetes V1.24版本起,kubelet彻底移除了dockershim,改为默认使用Containerd。这意味着如果用户在这个版本及之后部署Kubernetes集群,在没有额外配置的情况下,集群将使用Containerd作为容器运行时。不过,用户如果仍然希望使用Docker与Kubernetes集成,也可以通过使用cri-dockerd适配器来实现。
操作命令的变化
- 常用命令客户端改变:从使用Docker切换到使用Containerd后,以往常用的docker命令不再适用于新的容器运行时环境,取而代之的是crictl和ctr两个命令客户端。
- crictl是遵循CRI(Container Runtime Interface)接口规范的一个命令行工具,它主要用于检查和管理kubelet节点上的容器运行时和镜像,并且其操作基本都是在k8s.io命名空间下进行,与Kubernetes的集成更为紧密,比如可以用crictl ps查看运行中的容器、crictl images查看镜像等。
- ctr是containerd的一个客户端工具,用于直接操作Containerd。它相对更加底层,例如ctr -v可以输出Containerd的版本。ctr在操作镜像和容器时,需要注意区分不同的命名空间(主要有k8s.io、moby和default),不像crictl只有一个k8s.io命名空间。比如查看镜像列表时,ctr需要加上-n参数指定命名空间,如ctr -n=k8s.io image ls。
- 具体命令对比:以下是一些常见操作在使用Docker和使用Containerd(通过crictl和ctr)时的命令对比:
操作内容 docker ctr(containerd) crictl(kubernetes) 查看运行的容器 docker ps ctr task ls/ctr container ls crictl ps 查看镜像 docker images ctr image ls crictl images 查看容器日志 docker logs 无 crictl logs 查看容器数据信息 docker inspect ctr container info crictl inspect 查看容器资源 docker stats 无 crictl stats 启动/关闭已有的容器 docker start/stop ctr task start/kill crictl start/stop 运行一个新的容器 docker run ctr run 无(最小单元为pod) 打标签 docker tag ctr image tag 无 创建一个新的容器 docker create ctr container create crictl create 导入镜像 docker load ctr image import 无 导出镜像 docker save ctr image export 无 删除容器 docker rm ctr container rm crictl rm 删除镜像 docker rmi ctr image rm crictl rmi 拉取镜像 docker pull ctr image pull ctictl pull 推送镜像 docker push ctr image push 无 登录或在容器内部执行命令 docker exec 无 crictl exec 清空不用的容器 docker image prune 无 crictl rmi --prune
Kubernetes从使用Docker到使用Containerd的转变是容器技术发展和云原生生态完善的一个体现,虽然带来了操作命令等方面的一些变化,但也使得Kubernetes在容器运行时管理上更加高效、灵活和符合发展趋势。
以下是使用 ctr
命令和 crictl
命令列出Kubernetes(k8s)相关镜像的具体方法:
使用 crictl
命令列出k8s镜像
crictl
是遵循CRI接口规范的命令行工具,主要用于检查和管理kubelet节点上的容器运行时和镜像,并且其操作默认是在 k8s.io
命名空间下进行的。
要列出k8s的镜像,只需在安装了 crictl
且所在环境配置正确(一般在安装了k8s且相关配置完成后即可满足)的情况下,在命令行中执行以下命令:
crictl images
该命令会列出当前kubelet节点上在 k8s.io
命名空间下的所有镜像信息,包括镜像名称、标签、镜像ID等内容,示例输出可能如下:
IMAGE TAG IMAGE ID SIZE
k8s.gcr.io/pause:3.6 3.6 sha256:abcdef... 742kB
your-custom-image:latest latest sha256:123456... 5MB
使用 ctr
命令列出k8s镜像
ctr
是 containerd
的客户端工具,在使用它列出与k8s相关的镜像时,需要明确指定 k8s.io
命名空间,因为 ctr
操作涉及多个命名空间(如 k8s.io
、moby
、default
等),不像 crictl
只有一个 k8s.io
命名空间且默认在此空间操作。
以下是列出k8s镜像的 ctr
命令示例:
ctr -n k8s.io image ls
或者
ctr -n=k8s.io image ls
上述两种写法都可以正确指定 k8s.io
命名空间来列出该命名空间下的镜像。执行该命令后,会输出类似如下的内容,展示在 k8s.io
命名空间下的镜像信息:
REF TYPE DIGEST SIZE PLATFORM
k8s.gcr.io/pause:3.6 application/vnd.docker.image.rootfs.tar+gzip sha256:abcdef... 742kB linux/amd64
your-custom-image:latest application/vnd.docker.image.rootfs.tar+gzip sha256:123456... 5MB linux/amd64
通过以上 crictl
和 ctr
命令的操作,就可以分别列出Kubernetes相关的镜像信息了。
要向Kubernetes(k8s)中上传镜像,通常需要以下几个步骤,以下以常见的Docker镜像为例进行说明:
要向Kubernetes(k8s)中上传镜像,通常需要以下几个步骤,以下以常见的Docker镜像为例进行说明:
1. 准备镜像
确保你已经有了要上传到k8s集群的镜像,可以是自己构建的镜像或者从镜像仓库拉取的镜像。例如,你通过 docker build
命令构建了一个名为 your-app:v1
的应用镜像,或者从Docker Hub拉取了一个如 nginx:latest
的镜像。
以下是使用Docker制作镜像的一般步骤,这是目前最常见的制作镜像的方式:
1.1准备基础环境和文件
- 选择基础镜像:首先要根据你的应用需求选择一个合适的基础镜像。基础镜像提供了应用运行的底层环境,比如如果你要构建一个基于Python的应用程序镜像,可能会选择
python:3.8
作为基础镜像;如果是一个Web应用,可能会选择nginx
或apache
等作为基础镜像。基础镜像可以从公共镜像仓库(如Docker Hub)拉取。 - 准备应用文件:将你的应用程序相关文件整理好放在一个目录下。这可能包括可执行文件、配置文件、依赖库等。例如,对于一个Python应用,要把
.py
文件、requirements.txt
(用于指定Python依赖库)等放在一起。
1.2 编写Dockerfile
Dockerfile是一个文本文件,用于指导Docker如何构建镜像。它包含了一系列的指令,以下是一个简单的示例,假设要构建一个基于 python:3.8
基础镜像的Python应用镜像:
# 选择基础镜像
FROM python:3.8
# 设置工作目录
WORKDIR /app
# 复制应用文件到镜像内
COPY..
# 安装应用依赖库
RUN pip install -r requirements.txt
# 设置容器启动时执行的命令
CMD ["python", "main.py"]
在上述Dockerfile中:
FROM
指令选择了基础镜像python:3.8
。WORKDIR
指令设置了镜像内的工作目录为/app
。COPY
指令将当前目录(.
)下的所有文件复制到镜像内的工作目录/app
下。RUN
指令用于执行一些在镜像构建过程中需要完成的操作,这里是安装应用依赖库。CMD
指令设置了容器启动时执行的命令,这里是启动Python应用的主程序main.py
。
1.3 构建镜像
在编写好Dockerfile并确保应用文件都已准备好后,就可以构建镜像了。在包含Dockerfile和应用文件的目录下,执行以下命令:
docker build -t your-app:v1.
在上述命令中:
-t
选项用于给镜像指定名称和标签,这里我们给镜像命名为your-app:v1
,你可以根据自己的需要修改名称和标签。.
表示当前目录,即告诉Docker在当前目录下寻找Dockerfile来构建镜像。
执行该命令后,Docker会按照Dockerfile中的指令逐步构建镜像,这个过程可能会花费一些时间,具体取决于应用的复杂程度和网络状况等因素。
1.4 验证镜像
镜像构建完成后,可以通过以下几种方式验证镜像是否可用:
- 查看镜像列表:使用
docker images
命令查看是否成功构建了镜像,并且检查镜像的名称、标签、大小等信息。例如:
docker images
- 运行容器测试:使用
docker run
命令运行一个基于构建好的镜像的容器,看是否能正常启动并运行应用程序。例如:
docker run -it your-app:v1
在上述命令中, -it
表示以交互模式并分配一个终端给容器,以便可以观察容器内应用程序的运行情况。
通过以上步骤,就可以使用Docker制作出一个满足你应用需求的镜像了。当然,除了Docker,还有其他一些工具和方法也可以制作镜像,但Docker是目前应用最为广泛的一种。
2. 设置镜像仓库
- 选择镜像仓库类型:你需要选择一个合适的镜像仓库来存储和管理要上传的镜像。常见的镜像仓库有Docker Hub(公共的)、阿里云镜像仓库、腾讯云镜像仓库等(商业云平台提供的私有仓库),也可以自己搭建如Harbor等私有镜像仓库。
- 配置镜像仓库认证(如果需要):如果选择的是私有镜像仓库,通常需要进行认证配置,以便能够上传镜像。例如,对于阿里云镜像仓库,你需要在本地配置好阿里云账号的访问密钥等信息;对于Harbor等私有仓库,可能需要配置用户名和密码等。
3. 给镜像打标签(如果必要)
如果镜像的标签不符合你要上传到镜像仓库的要求,可能需要重新给镜像打标签。例如,要上传到Docker Hub的镜像,通常需要按照 username/repository:tag
的格式打标签,假设你的Docker Hub用户名是 your-username
,要上传上述 your-app:v1
镜像,就需要给它重新打标签为 your-username/your-app:v1
。
打标签的命令是:
docker tag your-app:v1 your-username/your-app:v1
4. 上传镜像到镜像仓库
- 使用Docker命令上传(以Docker Hub为例):
如果选择的是Docker Hub作为镜像仓库,且已经完成了上述步骤,就可以使用以下命令上传镜像:
docker push your-username/your-app:v1
这个命令会将打标签后的镜像上传到Docker Hub上对应的 your-username/your-app
仓库中,其他镜像仓库的上传命令类似,只是需要根据具体仓库的要求调整相关参数。
- 使用crictl上传(在k8s环境下,以containerd为运行时):
如果你的k8s集群使用containerd作为容器运行时,并且已经配置好了相关的镜像仓库信息,也可以使用crictl来上传镜像。首先要确保你已经在本地拉取了要上传的镜像(通过crictl pull
命令等),然后执行以下命令上传镜像:
crictl push your-app:v1 your-username/your-app:v1
这里假设要上传的镜像还是 your-app:v1
,且要上传到 your-username/your-app
仓库中,具体的命令参数要根据实际情况进行调整。
5. 在k8s中使用上传的镜像
一旦镜像上传成功,就可以在k8s的部署文件(如Deployment、Pod等配置文件)中指定要使用的镜像。例如,在一个Deployment配置文件中,你可以这样设置镜像:
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: your-app
template:
metadata:
matchLabels:
app: your-app
template:
containers:
- name: your-app-container
image: your-username/your-app:v1
这样,当你在k8s集群中部署这个Deployment时,就会使用你刚刚上传到镜像仓库的镜像来启动容器运行应用程序。
离线环境中本地导入镜像
ctr -n k8s.io i import xxx.tar
向k8s中上传镜像需要先准备好镜像,设置好镜像仓库,必要时给镜像打标签,然后通过合适的命令上传到镜像仓库,最后在k8s配置文件中指定使用上传的镜像。
以下是分别使用Docker和Containerd相关命令来导出某个镜像的具体方法:
使用Docker命令导出镜像
如果你当前的环境是基于Docker的,要导出一个镜像,可以使用 docker save
命令。
例如,要导出名为 nginx:latest
的镜像,执行以下命令:
docker save -o nginx_latest.tar nginx:latest
在上述命令中:
-o
选项用于指定输出文件的名称和路径,这里我们将导出的镜像文件命名为nginx_latest.tar
。nginx:latest
是要导出的镜像名称和标签组合。
执行该命令后,会在当前目录下生成一个名为 nginx_latest.tar
的文件,该文件包含了 nginx:latest
镜像的所有数据,包括分层文件系统、元数据等,可以用于在其他环境中导入该镜像进行使用。
使用Containerd相关命令导出镜像
当你的环境切换到使用Containerd作为容器运行时,要导出镜像则需要使用 ctr
命令(ctr
是 containerd
的客户端工具)。
假设要导出的镜像名称是 your-app:v1
,以下是导出该镜像的步骤:
首先,需要知道该镜像在 containerd
中的完整引用(REF),可以通过以下 ctr
命令查看镜像列表来获取:
ctr -n k8s.io image ls
假设通过上述命令查看到 your-app:v1
镜像的完整引用是 docker.io/your-app:v1
(实际情况可能因镜像来源等因素而不同),那么就可以使用以下命令来导出该镜像:
ctr -n k8s.io image export your-app_v1.tar docker.io/your-app:v1
在上述命令中:
-n k8s.io
指定了命名空间,因为ctr
操作涉及多个命名空间,这里假设镜像在k8s.io
命名空间下(根据实际情况调整)。image export
是ctr
命令用于导出镜像的操作。your-app_v1.tar
是要生成的导出文件的名称和路径,这里我们将其命名为your-app_v1.tar
。docker.io/your-app:v1
是要导出的镜像的完整引用,通过前面查看镜像列表获取到的。
执行该命令后,会在当前目录下生成一个名为 your-app_v1.tar
的文件,该文件包含了 your-app:v1
镜像的相关数据,可用于在其他地方导入使用。
无论是使用Docker还是Containerd,都可以通过相应的命令来导出某个镜像,以便在其他环境中进行导入和使用。