raspberry pi
Kubernetes是从一开始就设计为云原生的企业级容器编排系统。 它已发展成为事实上的云容器平台,并由于采用了容器本地虚拟化和无服务器计算等新技术而不断扩展。
Kubernetes在公共云和私有云环境中管理容器以及从边缘的微型到大规模的容器。 它是“私有云在家”项目的理想选择,既提供了强大的容器编排功能,又有机会了解这种需求的技术,并充分集成到云中,因此其名称实际上就是“云计算”的代名词。
没有什么像Kubernetes那样说“云”,也没有什么叫“聚集我!”的尖叫声。 很像树莓派。 在廉价的Raspberry Pi硬件上运行本地Kubernetes集群是获得在真正的云技术巨头上进行管理和开发的经验的好方法。
在Raspberry Pi上安装Kubernetes集群
本练习将在运行Ubuntu 20.04的三个或更多Raspberry Pi 4s上安装Kubernetes 1.18.2集群。 Ubuntu 20.04(Focal Fossa)提供了针对Raspberry Pi的64位ARM(ARM64)映像,该映像同时具有64位内核和用户空间。 由于目标是使用这些Raspberry Pi运行Kubernetes集群,因此运行AArch64容器映像的能力很重要:很难找到常见软件甚至标准基础映像的32位映像。 通过其ARM64映像,Ubuntu 20.04允许您在Kubernetes上使用64位容器映像。
AArch64与ARM64; 32位与64位; ARM与x86
请注意,AArch64和ARM64实际上是同一件事。 不同的名称源于它们在不同社区中的使用。 许多容器映像都标有AArch64,可以在标有ARM64的系统上正常运行。 具有AArch64 / ARM64体系结构的系统能够运行32位ARM映像,但事实并非如此:32位ARM系统不能运行64位容器映像。 这就是为什么Ubuntu 20.04 ARM64映像如此有用的原因。
为了两全其美,在本教程中设置Kubernetes集群后,可以在以后向其中添加x86_64节点。 您可以使用Kubernetes污点和容差来调度给定架构的图像,以通过Kubernetes的调度程序在适当的节点上运行。
足够了解架构和图像。 现在该安装Kubernetes了,开始吧!
要求
此练习的要求最低。 你会需要:
- 三个(或更多)Raspberry Pi 4s(最好是4GB RAM型号)
- 在所有Raspberry Pi上安装Ubuntu 20.04 ARM64
为了简化初始设置,请先阅读“ 修改磁盘映像以创建基于Raspberry Pi的家庭实验室,以将用户和SSH authored_keys添加到Ubuntu映像,然后再将其写入SD卡并安装在Raspberry Pi上。
配置主机
在Raspberry Pis上安装Ubuntu并通过SSH对其进行访问后,您需要进行一些更改,然后才能安装Kubernetes。
安装和配置Docker
在撰写本文时,Ubuntu 20.04在基础存储库中提供了Docker的最新版本v19.03,可以使用apt
命令直接安装。 请注意,软件包名称为docker.io
。 在所有Raspberry Pi上安装Docker:
# Install the docker.io package
$
sudo apt
install
-y docker.io
安装软件包后,您需要进行一些更改以启用cgroup (控制组)。 Cgroup允许Linux内核限制和隔离资源。 实际上,这使Kubernetes可以更好地管理其运行的容器使用的资源,并通过将容器彼此隔离来提高安全性。
在所有RPis上进行以下更改之前,请检查docker docker info
的输出:
# Check `docker info`
# Some output omitted
$
sudo docker info
( ...
)
Cgroup Driver: cgroups
( ...
)
WARNING: No memory limit support
WARNING: No swap limit support
WARNING: No kernel memory limit support
WARNING: No kernel memory TCP limit support
WARNING: No oom
kill disable support
上面的输出突出显示了需要更改的位:cgroup驱动程序和限制支持。
首先,将Docker使用的默认cgroups驱动程序从cgroups
更改为systemd
以允许systemd充当cgroups管理器,并确保仅使用一个cgroup管理器。 这有助于提高系统稳定性,Kubernetes建议这样做。 为此,请创建/etc/docker/daemon.json
文件或将其替换为:
# Create or replace the contents of /etc/docker/daemon.json to enable the systemd cgroup driver
$
sudo
cat
>
/ etc
/ docker
/ daemon.json
<<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
启用cgroups限制支持
接下来,启用限制支持,如上面的docker info
输出中的警告所示。 您需要修改内核命令行以在引导时启用这些选项。 对于Raspberry Pi 4,将以下内容添加到/boot/firmware/cmdline.txt
文件:
-
cgroup_enable=cpuset
-
cgroup_enable=memory
-
cgroup_memory=1
-
swapaccount=1
确保将它们添加到cmdline.txt
文件的行cmdline.txt
。 可以使用sed
在一行中完成:
# Append the cgroups and swap options to the kernel command line
# Note the space before "cgroup_enable=cpuset", to add a space after the last existing item on the line
$
sudo
sed
-i
'$ s/$/ cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1/'
/ boot
/ firmware
/ cmdline.txt
sed命令匹配行的终止(由第一个$
表示),将其替换为列出的选项(它将选项有效地附加到行)。
通过这些更改,应该根据需要为Kubernetes配置Docker和内核。 重新启动Raspberry Pi,当它们重新启动时,再次检查docker info
的输出。 现在, Cgroups driver
为systemd
,并且警告消失了。
允许iptables查看桥接流量
根据文档,Kubernetes需要配置iptables以查看桥接的网络流量。 您可以通过更改sysctl
配置来实现:
# Enable net.bridge.bridge-nf-call-iptables and -iptables6
cat
<< EOF
|
sudo
tee
/ etc
/ sysctl.d
/ k8s.conf
net.bridge.bridge-nf-call-ip6tables =
1
net.bridge.bridge-nf-call-iptables =
1
EOF
$
sudo sysctl
--system
为Ubuntu安装Kubernetes软件包
由于使用的是Ubuntu,因此可以从Kubernetes.io Apt存储库安装Kubernetes软件包。 当前没有适用于Ubuntu 20.04(Focal)的存储库,但最新的Ubuntu LTS存储库:Ubuntu 18.04(Xenial)中提供了Kubernetes 1.18.2。 可以从那里安装最新的Kubernetes软件包。
将Kubernetes存储库添加到Ubuntu的源代码中:
# Add the packages.cloud.google.com atp key
$ curl
-s https:
// packages.cloud.google.com
/ apt
/ doc
/ apt-key.gpg
|
sudo
apt-key add -
# Add the Kubernetes repo
cat
<< EOF
|
sudo
tee
/ etc
/ apt
/ sources.list.d
/ kubernetes.list
deb https:
// apt.kubernetes.io
/ kubernetes-xenial main
EOF
当Kubernetes添加Focal存储库时-也许在下一个Kubernetes版本发布时-确保切换到该库。
将存储库添加到源列表之后,安装三个必需的Kubernetes软件包:kubelet,kubeadm和kubectl:
# Update the apt cache and install kubelet, kubeadm, and kubectl
# (Output omitted)
$
sudo apt update
&&
sudo apt
install
-y kubelet kubeadm kubectl
最后,使用apt-mark hold
命令禁用这三个软件包的定期更新。 与常规更新过程相比,升级到Kubernetes需要更多的手动操作,并且需要手动注意:
# Disable (mark as held) updates for the Kubernetes packages
$
sudo
apt-mark hold kubelet kubeadm kubectl
kubelet
set on hold.
kubeadm
set on hold.
kubectl
set on hold.
这就是主机配置! 现在您可以继续设置Kubernetes本身。
创建一个Kubernetes集群
安装了Kubernetes软件包后,您可以继续创建集群。 在开始之前,您需要做出一些决定。 首先,需要将Raspberry Pi之一指定为Control Plane(即主节点)节点。 其余节点将被指定为计算节点。
您还需要选择一个网络CIDR以用于Kubernetes集群中的Pod。 在集群创建过程中设置pod-network-cidr
可确保设置podCIDR
值,并在以后由Container Network Interface(CNI)附加组件使用。 本练习使用法兰绒 CNI。 您选择的CIDR不应与家庭网络中当前使用的任何CIDR重叠,也不应与由路由器或DHCP服务器管理的CIDR重叠。 确保使用比您期望的子网更大的子网:总是有比您最初计划的要多的Pod! 在这个例子中,我将使用10.244.0.0/16,但是选择一个适合您的。
有了这些决定,您就可以初始化“控制平面”节点。 SSH或以其他方式登录到您为控制平面指定的节点。
初始化控制平面
Kubernetes使用引导令牌来验证要加入集群的节点。 初始化“控制平面”节点时,需要将此令牌传递给kubeadm init
命令。 生成令牌以与kubeadm token generate
命令一起使用:
# Generate a bootstrap token to authenticate nodes joining the cluster
$
TOKEN =$
(
sudo kubeadm token generate
)
$
echo
$TOKEN
d584xg.xupvwv7wllcpmwjy
现在,您可以使用kubeadm init
命令初始化控制平面了:
# Initialize the Control Plane
# (output omitted)
$
sudo kubeadm init
--token =
${TOKEN}
--kubernetes-version =v1.18.2
--pod-network-cidr =10.244.0.0
/
16
如果一切成功,则在输出末尾应该会看到类似的内容:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.2.114:6443 --token zqqoy7.9oi8dpkfmqkop2p5 \
--discovery-token-ca-cert-hash sha256:71270ea137214422221319c1bdb9ba6d4b76abfa2506753703ed654a90c4982b
请注意两点:首先,Kubernetes kubectl
连接信息已写入/etc/kubernetes/admin.conf
。 可以将root用户或普通用户的kubeconfig文件复制到~/.kube/config
,也可以复制到主节点或远程计算机上。 这将允许您使用kubectl
命令控制集群。
第二,以kubernetes join
开头的输出的最后一行是您可以运行的命令,用于将更多节点连接到集群。
将新的kubeconfig复制到用户可以使用的位置后,可以使用kubectl get nodes
命令验证是否已安装控制平面:
# Show the nodes in the Kubernetes cluster
# Your node name will vary
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
elderberry Ready master 7m32s v1.18.2
安装CNI附加组件
CNI附加组件处理Pod网络的配置和清理。 如前所述,此练习使用Flannel CNI插件。 设置好podCIDR
值后,您只需下载Flannel YAML并使用kubectl apply
其安装到集群中即可。 可以使用kubectl apply -f -
在一行上完成以从标准输入中获取数据。 这将创建管理Pod网络所需的ClusterRoles,ServiceAccounts和DaemonSet(等)。
下载Flannel YAML数据并将其应用于集群:
# Download the Flannel YAML data and apply it
# (output omitted)
$ curl
-sSL https:
// raw.githubusercontent.com
/ coreos
/ flannel
/ v0.12.0
/ Documentation
/ kube-flannel.yml
| kubectl apply
-f -
将计算节点加入集群
有了CNI附加组件之后,现在该将计算节点添加到群集了。 连接计算节点只是运行kube init
命令运行末尾提供的kubeadm join
命令以初始化控制平面节点的问题。 对于要加入群集的其他Raspberry Pi,请登录主机并运行以下命令:
# Join a node to the cluster - your tokens and ca-cert-hash will vary
$
sudo kubeadm
join 192.168.2.114:
6443
--token zqqoy7.9oi8dpkfmqkop2p5 \
--discovery-token-ca-cert-hash sha256:71270ea137214422221319c1bdb9ba6d4b76abfa2506753703ed654a90c4982b
在每个节点上完成加入过程之后,您应该能够在kubectl get nodes
的输出中看到新的kubectl get nodes
:
# Show the nodes in the Kubernetes cluster
# Your node name will vary
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
elderberry Ready master 7m32s v1.18.2
gooseberry Ready
< none
> 2m39s v1.18.2
huckleberry Ready
< none
> 17s v1.18.2
验证集群
至此,您已经拥有一个可以正常运行的Kubernetes集群。 您可以运行Pod,创建部署和作业等。您可以使用Services从集群中的任何节点访问集群中运行的应用程序。 您可以使用NodePort服务或入口控制器实现外部访问。
要验证集群是否正在运行,请创建新的名称空间,部署和服务,并检查部署中运行的Pod是否按预期进行响应。 此部署使用quay.io/clcollins/kube-verify:01
映像quay.io/clcollins/kube-verify:01
容器侦听请求(实际上,与使用Cloud-init将节点添加到私有云中的文章中使用的映像相同)。 您可以在此处查看图像Containerfile。
为部署创建一个名为kube-verify
的命名空间:
# Create a new namespace
$ kubectl create namespace kube-verify
# List the namespaces
$ kubectl get namespaces
NAME STATUS AGE
default Active 63m
kube-node-lease Active 63m
kube-public Active 63m
kube-system Active 63m
kube-verify Active 19s
现在,在新的名称空间中创建一个部署:
# Create a new deployment
$
cat
<< EOF
| kubectl create
-f -
apiVersion: apps
/ v1
kind: Deployment
metadata:
name: kube-verify
namespace: kube-verify
labels:
app: kube-verify
spec:
replicas:
3
selector:
matchLabels:
app: kube-verify
template:
metadata:
labels:
app: kube-verify
spec:
containers:
- name: nginx
image: quay.io
/ clcollins
/ kube-verify:01
ports:
- containerPort:
8080
EOF
deployment.apps
/ kube-verify created
Kubernetes现在将开始创建由三个Pod组成的部署,每个Pod运行quay.io/clcollins/kube-verify:01
映像。 kubectl get all -n kube-verify
一分钟后,新的Pod应该正在运行,您可以使用kubectl get all -n kube-verify
查看它们,并使用kubectl get all -n kube-verify
列出在新名称空间中创建的所有资源:
# Check the resources that were created by the deployment
$ kubectl get all
-n kube-verify
NAME READY STATUS RESTARTS AGE
pod
/ kube-verify-5f976b5474-25p5r
0
/
1 Running
0 46s
pod
/ kube-verify-5f976b5474-sc7zd
1
/
1 Running
0 46s
pod
/ kube-verify-5f976b5474-tvl7w
1
/
1 Running
0 46s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps
/ kube-verify
3
/
3
3
3 47s
NAME DESIRED CURRENT READY AGE
replicaset.apps
/ kube-verify-5f976b5474
3
3
3 47s
您可以看到新的部署,该部署创建的副本集以及该副本集创建的用于完成replicas: 3
三个Pod replicas: 3
在部署中的请求。 您可以看到Kubernetes的内部工作正常。
现在,创建一个服务以暴露在三个Pod中运行的Nginx“应用程序”(在本例中为“欢迎”页面)。 这将作为单个端点,您可以通过该端点连接到Pod:
# Create a service for the deployment
$
cat
<< EOF
| kubectl create
-f -
apiVersion: v1
kind: Service
metadata:
name: kube-verify
namespace: kube-verify
spec:
selector:
app: kube-verify
ports:
- protocol: TCP
port:
80
targetPort:
8080
EOF
service
/ kube-verify created
创建服务后,您可以对其进行检查并获取新服务的IP地址:
# Examine the new service
$ kubectl get
-n kube-verify service
/ kube-verify
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT
( S
) AGE
kube-verify ClusterIP 10.98.188.200
< none
>
80
/ TCP 30s
你可以看到, kube-verify
服务已经被分配一个ClusterIP(内部仅集群)的10.98.188.200
。 您可以从任何节点访问此IP,但不能从群集外部访问此IP。 您可以通过以下IP连接到它们来验证部署中的容器是否正常工作:
# Use curl to connect to the ClusterIP:
# (output truncated for brevity)
$ curl 10.98.188.200
<! DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
>
< html
xmlns =
"http://www.w3.org/1999/xhtml" xml:
lang =
"en"
lang =
"en"
>
<
head
>
成功! 您的服务正在运行,容器中的Nginx正在响应您的请求。
至此,您的Raspberry Pi上已经有一个正在运行的Kubernetes集群,其中安装了CNI附加组件(法兰),并且测试部署和服务正在运行Nginx Web服务器。 在大型公共云中,Kubernetes具有不同的入口控制器以与不同的解决方案进行交互,例如最近覆盖的Skipper项目。 同样,私有云具有用于与硬件负载平衡器设备(例如F5 Networks的负载平衡器)进行交互的入口控制器,或用于处理进入节点的流量的Nginx和HAProxy控制器。
在以后的文章中,我将通过安装自己的入口控制器来解决将群集中的服务暴露给外界的问题。 我还将研究用于为应用程序分配持久性存储的动态存储供应商和StorageClasses,包括利用您在上一篇文章“将Raspberry Pi家庭实验室转变为网络文件系统”中设置的NFS服务器,为您的应用创建按需存储。豆荚。
往前走,Kubernetes
“ Kubernetes”(κυβερνήτης)是希腊语的飞行员-但这是否意味着操纵船舶以及引导船舶的个人? 嗯不 “ Kubernan”(κυβερνάω)在希腊语中是“操纵”或“操纵”的意思,所以快点走吧,Kubernan,如果您在会议或其他场合看到我,请给我通行证以尝试动词名词。 来自另一种语言。 我不说话。
免责声明:如上所述,我不会读或不会讲希腊语,尤其是古老的希腊语,所以我选择相信自己在互联网上阅读的东西。 你知道那是怎么回事。 把它和一粒盐一起拿,然后给我一点休息,因为我没有开“对我来说都是希腊文”的玩笑。 但是,仅一提它,我就能够开玩笑而实际上却没有开玩笑,所以我要么偷偷摸摸,要么聪明,或者两者兼而有之。 或两者都不是。 我没有说这是个好玩笑。
因此,您可以在家中的私有云中使用自己的Kubernetes容器服务像专业人士一样试用您的容器! 当您变得更舒适时,可以修改Kubernetes集群以尝试其他选项,例如上述入口控制器和用于永久卷的动态StorageClasses。
这种持续的学习是DevOps的核心,新服务的持续集成和交付反映了敏捷方法论,当我们学会处理由云实现的大规模扩展并发现我们的传统做法时,我们都接受了这两种方法。无法跟上步伐。
看那个! 技术,政策,理念,希腊的一点点 ,和一个可怕元玩笑,一气呵成的文章!
翻译自: https://opensource.com/article/20/6/kubernetes-raspberry-pi
raspberry pi