由于本人电气出身,对于docker和kubernetes这两个东西可谓是深恶痛绝。然而项目需要,搬砖人只能默默自学了。k3s在自动驾驶中的项目还是很有可取之处的,而且docker也能够避免不同设备之间的系统版本问题。
因为目前的项目都是基于ros2 humble开发的,所以我们所有的节点都是使用ros2进行运行。之前,使用docker进行各个设备之间的数据交换已经完美运行,现在只需要加载到k3s平台就好。其实想想挺简单,然而自我怀疑智商不够的我,加上网上没有找到相关教程,硬生生的花了很多的时间把他啃下来。
两个重要的网站,很多博主都对他进行详细的介绍,可以去查阅他们的总结介绍:
docker
k3s
安装环境:
Ubuntu 22.04
首先需要修改host name, 但不是必要。
hostnamectl set-hostname master
在自己首次搭建环境时,我是已经通过docker网页安装了最新版本的docker engine 25.0.0。 然而它是我在搭建环境中的最大的障碍,后续一直出现错误,提示找不到镜像,我想原因是docker版本对不上。一定要安装rancher给的docker!!!
这是当前k3s版本适应的docker安装脚本:
curl https://releases.rancher.com/install-docker/20.10.sh | sh
根据官网的说明,继续安装k3s:
curl -sfL https://get.k3s.io | sh -s - --docker
结果如下:
root@master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 62m v1.28.5+k3s1
本人用ros2官网的publisher和subscriber的代码作为容器中的节点,作为例子ros2的包命名为my_ros2_package
接下来写一个简单的Dockerfile,并将他放到my_ros2_package的同级目录:
FROM ros:humble
WORKDIR /ros2_workspace
RUN apt-get update && apt-get install -y \
ros-humble-demo-nodes-cpp vim\
&& rm -rf /var/lib/apt/lists/*
COPY . /ros2_workspace/src
RUN . /opt/ros/${ROS_DISTRO}/setup.sh && cd /ros2_workspace && \
colcon build
CMD ["bash"]
然后将ros包编译成docker的容器镜像:
docker build -t ros2_example:latest -f Dockerfile .
得到以下结果:
root@master:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ros2_example latest 2637c201e7d1 50 minutes ago 800MB
ros humble b4f3523df228 3 days ago 752MB
接下来写一个deployment.yaml文件,将ros2_example:latest镜像作为k3s集群中的一个cluster的应用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ros2-talker
labels:
app: ros2-talker
spec:
selector:
matchLabels:
app: ros2-talker
template:
metadata:
labels:
app: ros2-talker
spec:
nodeSelector:
kubernetes.io/hostname: master
containers:
- name: ros2-talker
image: ros2_example:latest
command: ["/bin/sh", "-c"]
args: [". /opt/ros/humble/setup.sh && . install/local_setup.sh && ros2 run my_ros2_package talker"]
imagePullPolicy: IfNotPresent
这里的imagePullPolicy: IfNotPresent很重要,否则找不到本地的docker镜像,因为它默认是寻找docker Hub的镜像。
kubernetes.io/hostname: master 这里需要和你设备的hostname一致,否则无法将应用添加到k3s集群中去。
sudo kubectl apply -f deployment.yaml
结果如下:
root@master:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
ros2-talker-84c4ff4654-x4npj 1/1 Running 0 51m
看到running的状态就表示,环境搭建成功!!!
如果看到pending的状态,那么就是哪里出现问题了,可以通过 kubectl describe pod pod-name 查看节点的运行log,下面是一个示例:
root@master:~# kubectl describe pod ros2-talker-84c4ff4654-x4npj
Name: ros2-talker-84c4ff4654-x4npj
Namespace: default
Priority: 0
Service Account: default
Node: master/192.168.0.105
Start Time: Sat, 20 Jan 2024 15:10:46 +0100
Labels: app=ros2-talker
pod-template-hash=84c4ff4654
Annotations:
Status: Running
IP: 10.42.0.10
IPs:
IP: 10.42.0.10
Controlled By: ReplicaSet/ros2-talker-84c4ff4654
Containers:
ros2-talker:
Container ID: docker://4e2bc1405e1e02fb442122c8e8345e827bab911414cb65852e0b4e35018c206f
Image: ros2_example:latest
Image ID: docker://sha256:2637c201e7d18098f0597b83997a071fbe1b4591cef614c733e6eec4368d641f
Port:
Host Port:
Command:
/bin/sh
-c
Args:
. /opt/ros/humble/setup.sh && . install/local_setup.sh && ros2 run my_ros2_package talker
State: Running
Started: Sat, 20 Jan 2024 15:10:49 +0100
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bnvvf (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-bnvvf:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional:
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: kubernetes.io/hostname=master
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 53m default-scheduler Successfully assigned default/ros2-talker-84c4ff4654-x4npj to master
Normal Pulled 53m kubelet Container image "ros2_example:latest" already present on machine
Normal Created 53m kubelet Created container ros2-talker
Normal Started 53m kubelet Started container ros2-talker
可以通过message来查看哪里出现了问题,并去解决问题。
接下来进入该节点,并管理该节点:
kubectl exec --stdin --tty ros2-talker-84c4ff4654-x4npj -- /bin/bash
进入该节点的容器后,就可以正常查看ros2的topic的信息了。当然,首先需要通过source bash文件加载ros2的环境。
查看最终结果:
root@ros2-talker-84c4ff4654-x4npj:/ros2_workspace# ros2 topic list
/parameter_events
/rosout
/topic
root@ros2-talker-84c4ff4654-x4npj:/ros2_workspace# ros2 topic echo /topic
data: 'Hello World: 7056'
---
data: 'Hello World: 7057'
---
data: 'Hello World: 7058'
---
data: 'Hello World: 7059'
---
data: 'Hello World: 7060'
---
到目前为止,搭载k3s的server就完成了。因为该环境不是在国内搭载的,所以使用的安装链接都是官网提供的链接。在其他博客中也看到了更适合在国内使用的链接,大家可以参考他们的链接。
由于设备原因,目前无法在第二台终端安装k3s agent,并实现listener节点在agent运行。因为ros2的通信在不同设备中的docker出现了很多问题,希望k3s的ros2通信能够顺利实现。该篇有时间会后续发布。
本人第一次写博客,记录一下自己在打怪路上的一些心得,希望也能够对别人有帮助。不足之处可以提出建议。