相信大家在2020年歲末都被Kubernetes即將拋棄Docker
的消息刷屏了迄汛。事實上作為接替Docker運行時的Containerd在早在Kubernetes1.7時就能直接與Kubelet集成使用,只是大部分時候我們因熟悉Docker续誉,在部署集群時采用了默認(rèn)的dockershim。不過社區(qū)也說了初肉,在1.20之后的版本的kubelet會放棄對dockershim部分的支持酷鸦。
作為普通小白,我們在更換Containerd后,以往的一些習(xí)慣和配置也不得不改變和適配臼隔。那么本篇也是最近小白逐漸替換Containerd后的一些總結(jié)嘹裂。
1. Containerd安裝與Kubelet集成
- 安裝前的準(zhǔn)備
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 設(shè)置必需的 sysctl 參數(shù),這些參數(shù)在重新啟動后仍然存在躬翁。
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
- 安裝containerd
# 安裝 Docker 的官方 GPG 密鑰
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -
# 新增 Docker apt 倉庫焦蘑。
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 安裝containerd包
sudo apt-get update && sudo apt-get install -y containerd.io
- 生成containerd默認(rèn)配置
sudo mkdir -p /etc/containerd
sudo containerd config default > /etc/containerd/config.toml
- 修改kubelet配置
在配置文件/var/lib/kubelet/kubeadm-flags.env的KUBELET_KUBEADM_ARGS追加以下部分
KUBELET_KUBEADM_ARGS="--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock --image-service-endpoint=unix:///run/containerd/containerd.sock"
- 重啟containerd和kubelet服務(wù)
systemctl restart containerd kubelet
2. Containerd常見操作
更換Containerd后盯拱,以往我們常用的docker命令也不再使用盒发,取而代之的分別是crictl和ctr兩個命令客戶端。
- crictl是遵循CRI接口規(guī)范的一個命令行工具狡逢,通常用它來檢查和管理kubelet節(jié)點上的容器運行時和鏡像
- ctr是containerd的一個客戶端工具宁舰,
使用crictl命令之前,需要先配置/etc/crictl.yaml
如下:
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
接下來就是crictl的的常見命令奢浑,其中能完全替代docker命令的參照下列表格
操作 | crictl | docker |
---|---|---|
查看運行容器 | crictl ps | docker ps |
查看鏡像 | crictl images | docker images |
查看容器日志 | crictl logs | docker logs |
登陸容器控制臺 | crictl exec | docker exec |
pull鏡像 | crictl pull | docker pull |
容器啟動/停止 | crictl start/stop | docker start/stop |
容器資源情況 | crictl stats | docker stats |
可以看到crictl對容器生命周期的管理基本已經(jīng)覆蓋蛮艰,不過在crictl我們不能完成操作也比較多,比如對鏡像的管理就不屬于它的管理范圍雀彼。這部分還得依靠ctr來實現(xiàn)壤蚜,操作方式同樣可以參照下表
操作 | ctr | docker |
---|---|---|
查看鏡像 | ctr images ls | docker images |
鏡像導(dǎo)入/導(dǎo)出 | ctr images import/exporter | docker load/save |
鏡像拉取/推送 | ctr images pull/push | docker pull/push |
鏡像tag | ctr images tag | docker tag |
這里需注意的是,由于Containerd也有namespaces的概念徊哑,對于上層編排系統(tǒng)的支持袜刷,主要區(qū)分了3個命名空間分別是k8s.io
、moby
和default
莺丑,以上我們用crictl操作的均在k8s.io命名空間完成如查看鏡像列表就需要加上-n
參數(shù)
ctr -n k8s.io images list
3. Containerd與(虛擬)顯卡設(shè)備
在Docker中著蟹,通常用nvidia-docker來調(diào)用nvidia-container-runtime
來實現(xiàn)容器的GPU設(shè)備掛載。在更換成Containerd后梢莽,我們就不再需要nvidia-docker這個客戶端萧豆,而是直接在containerd運行時的plugin中直接調(diào)用nvidia-container-runtime
除了需要正常安裝containerd和nvidia、cuda驅(qū)動外昏名,還需要安裝nvidia-container-runtime
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt update
sudo apt install nvidia-container-runtime -y
最后在containerd添加nvidia運行時配置
/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
- default_runtime_name = "runc"
+ default_runtime_name = "nvidia"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
# This section is added by system, we can just ignore it.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
runtime_engine = ""
runtime_root = ""
privileged_without_host_devices = false
base_runtime_spec = ""
+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]
+ runtime_type = "io.containerd.runc.v2"
+ runtime_engine = ""
+ runtime_root = ""
+ privileged_without_host_devices = false
+ base_runtime_spec = ""
+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]
+ BinaryName = "nvidia-container-runtime"
此外如果你和小白一樣用了騰訊的tke-gpu-manager
來虛擬化GPU設(shè)備的話涮雷,還需要將gpu-manager升級到1.1.0版本以上。然后修改啟動參數(shù)即可解決
containers:
- env:
- name: EXTRA_FLAGS
value: --container-runtime-endpoint=/var/run/containerd/containerd.sock
最后我們用一個pod來驗證GPU是否能正常識別到即可
apiVersion: v1
kind: Pod
metadata:
name: vcuda
spec:
restartPolicy: Never
containers:
- image: nvidia/cuda:10.1-runtime-ubuntu16.04
name: nvidia
command:
- "/usr/local/nvidia/bin/nvidia-smi"
- "pmon"
- "-d"
- "10"
resources:
requests:
tencent.com/vcuda-core: 50
tencent.com/vcuda-memory: 4
limits:
tencent.com/vcuda-core: 50
tencent.com/vcuda-memory: 4
4. Containerd控制臺日志
在Docker時代轻局,kubernetes的容器控制日志默認(rèn)格式為json份殿,在更換為Containerd后,容器的控制臺輸出變?yōu)閠ext格式嗽交,如下
# docker的json格式日志
{"log":"[INFO] plugin/reload: Running configuration MD5 = 4665410bf21c8b272fcfd562c482cb82\n","stream":"stdout","time":"2020-01-10T17:22:50.838559221Z"}
#contaienrd的text格式日志
2020-01-10T18:10:40.01576219Z stdout F [INFO] plugin/reload: Running configuration MD5 = 4665410bf21c8b272fcfd562c482cb82
大多情況情況下這會導(dǎo)致我們默認(rèn)的日志采集客戶端以前用json格式解析器報錯而無法繼續(xù)采集日志
卿嘲,所以當(dāng)我們把Containerd上線后還需要修改日志采集端的配置。
以fluentd為樣例夫壁,我們需要引入multi_format
來解析兩種格式的容器日志
<source>
@id fluentd-containers.log
@type tail
path /var/log/containers/*.log
pos_file /var/log/es-containers.log.pos
tag raw.kubernetes.*
read_from_head true
<parse>
@type multi_format
<pattern>
format json
time_key time
time_format %Y-%m-%dT%H:%M:%S.%NZ
</pattern>
#這部分用來正則匹配CRI容器日志格式
<pattern>
format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
time_format %Y-%m-%dT%H:%M:%S.%N%:z
</pattern>
</parse>
</source>
總結(jié)
K8S的Worker節(jié)點逐漸的往輕量化轉(zhuǎn)移拾枣,除了Containerd之外還有k8s的親兒子cri-o,不過相比Containerd已經(jīng)過大規(guī)模生產(chǎn)環(huán)境驗證的產(chǎn)品來講,當(dāng)下Containerd仍然是最佳的容器運行時管理工具梅肤。
關(guān)注公眾號「云原生小白」司蔬,獲取更多精彩內(nèi)容