kubeadm
- 1. docker 和 containerd
- 1.1 命令区分
- 1.2 常用命令
- 1.3 关于crictl
- 2. 示例
- 2.1 部署nginx
先从一个报错开始吧
[root@node-129 kubernetes]# crictl ps
WARN[0000] runtime connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
WARN[0000] image connect using default endpoints: [unix:///var/run/dockershim.sock unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.
E0717 03:21:14.371287 48865 remote_runtime.go:390] "ListContainers with filter from runtime service failed" err="rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory\"" filter="&ContainerFilter{Id:,State:&ContainerStateValue{State:CONTAINER_RUNNING,},PodSandboxId:,LabelSelector:map[string]string{},}"
FATA[0000] listing containers: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or directory"
错误信息可以看到crictl连接的runtime是docker,并且连接失败。查看containerd启动信息(journalctl -exu containerd),containerd启动完成后监听的unix sock路径是:/run/containerd/containerd.sock。
创建crictl配置文件:/etc/crictl.yaml。修改crictl默认配置,把runtime-endpoint和image-endpoint指向containerd
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: true
pull-image-on-create: false
修改后
[root@node-129 kubernetes]# crictl ps
DEBU[0000] get runtime connection
DEBU[0000] get image connection
DEBU[0000] ListContainerResponse:
...
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
4ceba0f7bfc5a 38c11b8f4aa19 52 minutes ago Running kube-flannel 0 567933503bde5 kube-flannel-ds-bxvqv
d2572be6709d3 5f82fc39fa816 About an hour ago Running kube-proxy 0 2f0c651c078ab kube-proxy-wc9zz
d5cedeb28123c 86b6af7dd652c About an hour ago Running etcd 1 ca981be82701c etcd-node-129
8d4fe5da9d6ce 95fe52ed44570 About an hour ago Running kube-controller-manager 1 b0920110bc805 kube-controller-manager-node-129
46d11f2893f06 6f707f569b572 About an hour ago Running kube-apiserver 1 11762c37e44d5 kube-apiserver-node-129
de7f51d606efa f73f1b39c3fe8 About an hour ago Running kube-scheduler 1 e33497db48470 kube-scheduler-node-129
由于本次部署k8s使用kubeadm,而其容器引擎使用的是containerd,作为新产品(相对于docker),他们有什么区别与联系呢?
1. docker 和 containerd
- docker 由 docker-client ,dockerd,containerd,docker-shim,runc 组成,所以 containerd 是 docker 的基础组件之一
- 从 k8s 的角度看,可以选择 containerd 或 docker 作为运行时组件:其中 containerd 调用链更短,组件更少,更稳定,占用节点资源更少。所以 k8s 后来的版本开始默认使用 containerd 。
- containerd 相比于 docker , 多了 namespace 概念,每个 image 和 container 都会在各自的 namespace 下可见。
- docker 作为 k8s 容器运行时,调用关系为:kubelet --> dockershim (在 kubelet 进程中) --> dockerd --> containerd
containerd 作为 k8s 容器运行时,调用关系为:kubelet --> cri plugin(在 containerd 进程中) --> containerd
至于docker和containerd的恩怨情仇,前文中已经提及,此处不再赘述。
1.1 命令区分
- ctr 是 containerd 的一个客户端工具。
- crictl 是 CRI 兼容的容器运行时命令行接口,可以使用它来检查和调试 k8s 节点上的容器运行时和应用程序。
ctr -v 输出的是 containerd 的版本,crictl -v 输出的是当前 k8s 的版本,从结果显而易见你可以认为 crictl 是用于 k8s 的。
[root@node-129 kubernetes]# crictl -v
crictl version v1.26.0
[root@node-129 kubernetes]# ctr -v
ctr containerd.io 1.6.21
所以说某个主机安装了 k8s 后,命令行才会有 crictl 命令。而 ctr 是跟 k8s 无关的,主机安装了 containerd 服务后就可以操作 ctr 命令。
1.2 常用命令
又是一大波的命令来袭
命令 | 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 |
ctr并没有build命令,也就是没办法构建镜像,怎么办呢?
containerd 有一个子项目:nerdctl ,用来兼容 docker cli,可以像 docker 命令一样来管理本地的镜像和容器
想深入了解的朋友可以参考containerd 镜像构建工具 – nerdctl 和 buildkit
1.3 关于crictl
#查看containerd客户端即服务器版本信息
ctr version
#ctr全局命令概览
[root@localhost ~]# ctr --help
USAGE: (注意看这个格式:ctr 全局选项 命令 命令选项 参数)ctr [global options] command [command options] [arguments...]
COMMANDS:plugins, plugin provides information about containerd pluginsversion 打印客户端和服务端版本containers, c, container 管理containerscontent 管理contentevents, event 显示containerd eventsimages, image, i 管理镜像leases 管理leasesnamespaces, namespace, ns 管理namespacespprof provide golang pprof outputs for containerdrun 运行一个containersnapshots, snapshot 管理snapshotstasks, t, task 管理tasksinstall 安装一个新的packageoci OCI toolsshim interact with a shim directlyhelp, h 显示命令帮助全局选项:--debug 在logs中开启enable输出--address value, -a value containerd's GRPC server的地址 (默认: "/run/containerd/containerd.sock") --timeout value ctr命令超时时间(默认: 0s)--connect-timeout value 连接containerd超时时间 (默认: 0s)--namespace value, -n value 命名空间 (默认: "default")--help, -h 显示帮助--version, -v 打印版本信息
万幸的是,containerd和docker的镜像是通用的(想想也是,真想直接取代docker也不太可能的,毕竟受众在那呢)
[root@node-129 kubernetes]# ctr image import my.tar
unpacking docker.io/library/mypython:latest (sha256:962b1654766f57616a6f36a67e8eaac6c67b13e79207f4864d85ab1a5641bdc5)...done
[root@node-129 kubernetes]# ctr i ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/mypython:latest application/vnd.docker.distribution.manifest.v2+json sha256:962b1654766f57616a6f36a67e8eaac6c67b13e79207f4864d85ab1a5641bdc5 348.5 MiB linux/amd64 -
[root@node-129 kubernetes]# ctr i tag docker.io/library/mypython:latest mypython:latest
mypython:latest
[root@node-129 kubernetes]# ctr i ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/mypython:latest application/vnd.docker.distribution.manifest.v2+json sha256:962b1654766f57616a6f36a67e8eaac6c67b13e79207f4864d85ab1a5641bdc5 348.5 MiB linux/amd64 -
mypython:latest application/vnd.docker.distribution.manifest.v2+json sha256:962b1654766f57616a6f36a67e8eaac6c67b13e79207f4864d85ab1a5641bdc5 348.5 MiB linux/amd64 -
2. 示例
2.1 部署nginx
[root@node-128 kubernetes]# cat nginx-svc-deploy.yaml
apiVersion: v1
kind: Service
metadata:labels:app: nginx-serviename: nginx-servicenamespace: hello-world
spec:ports:- nodePort: 30013port: 80protocol: TCPtargetPort: 80selector:app: nginx-podtype: NodePort---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-deployname: nginx-deploynamespace: hello-world
spec:replicas: 1selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podnamespace: hello-worldspec:containers:- image: docker.io/library/nginx:latestname: nginxports:- containerPort: 80resources: {}
我们先创建命名空间hello-world,然后部署
[root@node-128 kubernetes]# kubectl create namespace hello-world
namespace/hello-world created
[root@node-128 kubernetes]# kubectl apply -f nginx-svc-deploy.yaml
service/nginx-service created
deployment.apps/nginx-deploy created
[root@node-128 kubernetes]# kubectl get pods -n hello-world
NAME READY STATUS RESTARTS AGE
nginx-deploy-65fcf47dd5-62sgb 1/1 Running 0 6m42s
可以看到我们访问VIP展现了nginx的主页面
[root@node-128 kubernetes]# curl http://192.168.17.120:30013/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>