Centos8 ARM64
一、认识
在本文中,我们将详细介绍如何在 Apple M1 Mac
上使用 VMFunction
虚拟机安装 CentOS 8 ARM64
系统,并在此基础上搭建一个 Kubernetes
集群,采用 containerd
作为容器运行时。随着 ARM64
架构在现代计算中的普及,特别是 Apple M1
芯片的广泛应用,了解如何在 ARM64
平台上部署和管理 Kubernetes
集群变得尤为重要。本文将涵盖从在 M1 Mac
上设置虚拟机、安装 CentOS 8 ARM64
,到配置 Kubernetes
集群和使用 containerd
运行时的完整过程,帮助您在 ARM64
环境中高效地运行 Kubernetes
。
二、初始化前准备
2.1 配置主机名
配置主机名对集群管理至关重要。Kubernetes
集群中的节点需要通过主机名来识别和通信。
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2
2.2 配置时间同步
时间同步确保集群中的所有节点时间一致,避免时间偏差影响集群操作。使用 chrony
来同步时间。
1. 配置时间同步
yum install -y chrony
systemctl start chronyd
systemctl enable chronyd
2. 验证时间同步
sleep 4
chronyc sources
2.3 配置 Hosts
将集群节点的 IP
地址和主机名添加到 /etc/hosts
文件中,确保节点能够通过主机名互相识别。
K8S_HOST_ENTRIES=(
"192.168.105.132 k8s-master"
"192.168.105.133 k8s-node1"
"192.168.105.134 k8s-node2"
)
update_hosts() {
for entry in "${K8S_HOST_ENTRIES[@]}"; do
if ! grep -q "$entry" /etc/hosts; then
echo "$entry" >> /etc/hosts || handle_error "Failed to update /etc/hosts with $entry"
echo "/etc/hosts updated with $entry"
else
echo "/etc/hosts already contains $entry"
fi
done
}
2.4 关闭 Swap
Kubernetes
的 kubelet
组件依赖系统内存调度策略,关闭 Swap
可以防止内存分配不确定性,确保 kubelet
的稳定性。
1. 关闭 Swap
swapoff -a # 临时
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 永久
2. 验证 Swap
是否关闭
free
2.5 关闭防火墙
为了确保 Kubernetes
组件之间的自由通信,需关闭防火墙。
1. 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
2, 检测防火墙状态
systemctl status firewalld
2.6 关闭 Selinux
SELinux
的安全策略可能会阻止 Kubernetes
的操作。关闭 SELinux
以确保服务能够正常启动。
1. 关闭 Selinux
setenforce 0 # 临时
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 永久
2. 验证 SeLinux
是否关闭
getenforce // 结果为 Permissive, 则表示 setenforce 已成功关闭 SELinux。
2.7 配置 Iptables
正确配置 Iptables
是集群网络正常运行的关键,确保 Kubernetes
组件能够正确处理网络流量。
yum install ipset ipvsadm -y
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe ip_vs
sudo modprobe overlay
sudo modprobe ip_vs_sh
sudo modprobe ip_vs_rr
sudo modprobe ip_vs_wrr
sudo modprobe br_netfilter
sudo modprobe nf_conntrack_ipv4
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
# 应用 sysctl 参数而不重新启动
sudo sysctl --system
# 通过运行以下指令确认 br_netfilter 和 overlay 模块被加载
lsmod | grep br_netfilter
lsmod | grep overlay
# 通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在你的 sysctl 配置中被设置为 1
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
2.8 配置 Docker Cgroup 驱动
通过 yum
的方式安装 docker-ce
, 同时会安装 containerd
、runc
、cni
、crictl
。安装成功后,配置 Docker
驱动方式。Kubernetes
和 Docker
使用 cgroup
来管理资源,配置一致的 cgroup
驱动可以避免管理不一致性和潜在的资源竞争问题。更改 /etc/docker/daemon.json
配置如下:
# 配置加速器
DOCKER_MIRROR_URL="https://624m5g3q.mirror.aliyuncs.com"
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["'$DOCKER_MIRROR_URL'", "https://registry.docker-cn.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
# 重启 Docker
systemctl restart docker
2.9 配置 Containerd 运行时
通过 yum
的方式安装 docker-ce
, 同时会安装 containerd
、runc
、cni
、crictl
。containerd
是 Kubernetes
推荐的容器运行时,它与 Kubernetes
集成良好并提供更轻量级的容器管理。配置 containerd
作为容器运行时,并设置镜像加速器,优化容器管理和镜像拉取速度。
1. 配置 containerd
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
#1. 添加 config_path = "/etc/containerd/certs.d"
sed -i 's/config_path\ =.*/config_path = \"\/etc\/containerd\/certs.d\"/g' /etc/containerd/config.toml
mkdir /etc/containerd/certs.d/docker.io -p
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."https://624m5g3q.mirror.aliyuncs.com"]
capabilities = ["pull", "resolve"]
EOF
#2. 把SystemdCgroup = false修改为:SystemdCgroup = true
sed -i 's/SystemdCgroup\ =\ false/SystemdCgroup\ =\ true/g' /etc/containerd/config.toml
#3. 把sandbox_image = "k8s.gcr.io/pause:3.6"修改为:sandbox_image="registry.aliyuncs.com/google_containers/pause:3.9"
sed -i 's/sandbox_image\ =.*/sandbox_image\ =\ "registry.aliyuncs.com\/google_containers\/pause:3.8"/g' /etc/containerd/config.toml|grep sandbox_image
2. 启动 containerd
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
3. 验证 containerd
sudo systemctl status containerd
2.10 配置 CriCtl 容器管理
通过 yum
的方式安装 docker-ce
, 同时会安装 containerd
、runc
、cni
、crictl
。配置 crictl
作为 CRI
兼容的容器运行时命令行工具,用于检查和调试 Kubernetes
节点上的容器运行时。
1. 配置 CriCtl
容器管理
cat >> /etc/crictl.yaml << EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: true
EOF
2. 重启 containerd
systemctl restart containerd
3. 验证 CriCtl
crictl --version
2.11 将以上操作步骤沉淀为脚本
1. 沉淀脚本,并命名为 prepare_kubernetes.sh
#!/bin/bash
set -e # 遇到错误时停止脚本执行
# 主机 IP 和名称配置
declare -A K8S_HOST_ENTRIES=(
["192.168.105.132"]="k8s-master"
["192.168.105.133"]="k8s-node1"
["192.168.105.134"]="k8s-node2"
)
CONTAINERD_CONFIG_FILE="/etc/containerd/config.toml"
DOCKER_MIRROR_URL="https://624m5g3q.mirror.aliyuncs.com"
handle_error() {
echo "Error: $1"
exit 1
}
check_root() {
if [ "$(id -u)" -ne 0 ]; then
handle_error "This script must be run as root. Please run as root or with sudo."
fi
}
set_hostname() {
echo "============"
echo "开始配置主机名"
echo "============"
local HOSTNAME=$1
if [ "$(hostnamectl --static)" != "$HOSTNAME" ]; then
hostnamectl set-hostname "$HOSTNAME" || handle_error "Failed to set hostname to $HOSTNAME"
echo "Hostname set to $HOSTNAME"
else
echo "Hostname is already set to $HOSTNAME"
fi
echo "============"
echo "主机名配置成功!"
echo "============"
}
configure_time_sync() {
echo "============"
echo "开始配置时间同步"
echo "============"
yum install -y chrony || handle_error "Failed to install chrony"
systemctl start chronyd || handle_error "Failed to start chronyd"
systemctl enable chronyd || handle_error "Failed to enable chronyd"
sleep 4
chronyc sources || handle_error "Failed to check time synchronization sources"
echo "============"
echo "时间同步成功!"
echo "============"
}
update_hosts() {
echo "============"
echo "开始更新 /etc/hosts 文件"
echo "============"
for IP in "${!K8S_HOST_ENTRIES[@]}"; do
local HOSTNAME=${K8S_HOST_ENTRIES[$IP]}
if ! grep -q "$IP $HOSTNAME" /etc/hosts; then
echo "$IP $HOSTNAME" >> /etc/hosts || handle_error "Failed to update /etc/hosts with $IP $HOSTNAME"
echo "/etc/hosts updated with $IP $HOSTNAME"
else
echo "/etc/hosts already contains $IP $HOSTNAME"
fi
done
echo "============"
echo "更新 /etc/hosts 文件 成功!"
echo "============"
}
disable_swap() {
echo "============"
echo "开始关闭 Swap"
echo "============"
swapoff -a || handle_error "Failed to turn off swap"
sed -ri 's/.*swap.*/#&/' /etc/fstab || handle_error "Failed to update /etc/fstab for swap"
echo "============"
echo "Swap 关闭成功!"
echo "============"
}
disable_firewalld() {
echo "============"
echo "开始关闭防火墙"
echo "============"
systemctl stop firewalld || handle_error "Failed to stop firewalld"
systemctl disable firewalld || handle_error "Failed to disable firewalld"
echo "============"
echo "防火墙关闭成功!"
echo "============"
}
disable_selinux() {
echo "============"
echo "开始关闭 SELinux"
echo "============"
setenforce 0 || handle_error "Failed to set SELinux to permissive mode"
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config || handle_error "Failed to update /etc/selinux/config"
echo "============"
echo "SELinux 关闭成功!"
echo "============"
}
configure_iptables() {
echo "============"
echo "开始配置 Iptables"
echo "============"
if ! command -v yum &> /dev/null; then
handle_error "yum command not found"
fi
if [ "$(id -u)" -ne 0 ]; then
handle_error "This script must be run as root"
fi
yum install -y ipset ipvsadm || handle_error "Failed to install ipset"
IPTABLES_MODULES_CONF="/etc/modules-load.d/k8s.conf"
IPTABLES_SYSCTL_CONF="/etc/sysctl.d/k8s.conf"
cat <<EOF | tee "$IPTABLES_MODULES_CONF"
overlay
br_netfilter
EOF
for module in overlay br_netfilter ip_vs ip_vs_sh ip_vs_rr ip_vs_wrr nf_conntrack; do
modprobe "$module" || handle_error "Failed to load $module module"
done
cat <<EOF | tee "$IPTABLES_SYSCTL_CONF"
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
sysctl --system || handle_error "Failed to apply sysctl settings"
lsmod | grep -E 'overlay|br_netfilter' || handle_error "Required iptables modules are not loaded"
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward || handle_error "Failed to verify sysctl settings"
# 配置 kubelet
if [ -f /etc/sysconfig/kubelet ]; then
cat >> /etc/sysconfig/kubelet << EOF
# KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
EOF
else
handle_error "/etc/sysconfig/kubelet file not found"
fi
echo "============"
echo "Iptables 配置成功!"
echo "============"
}
configure_docker() {
echo "============"
echo "开始配置 Docker Cgroup 驱动"
echo "============"
DOCKER_CONFIG_FILE="/etc/docker/daemon.json"
cat > "$DOCKER_CONFIG_FILE" << EOF
{
"registry-mirrors": ["$DOCKER_MIRROR_URL", "https://registry.docker-cn.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
systemctl restart docker || handle_error "Docker 重启失败"
echo "============"
echo "Docker Cgroup 配置驱动成功!"
echo "============"
}
configure_containerd() {
echo "============"
echo "开始配置 Containerd"
echo "============"
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee "$CONTAINERD_CONFIG_FILE"
# 修改配置文件中的默认值
sed -i 's/SystemdCgroup\ =\ false/SystemdCgroup\ =\ true/g' "$CONTAINERD_CONFIG_FILE"
sed -i 's/sandbox_image\ =.*/sandbox_image\ =\ "registry.aliyuncs.com\/google_containers\/pause:3.9"/g' "$CONTAINERD_CONFIG_FILE"
sed -i 's/config_path\ =.*/config_path = \"\/etc\/containerd\/certs.d\"/g' "$CONTAINERD_CONFIG_FILE"
# 添加镜像加速器
mkdir -p /etc/containerd/certs.d/docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
server = "https://docker.io"
[host."$DOCKER_MIRROR_URL"]
capabilities = ["pull", "resolve"]
EOF
echo "============"
echo "配置 Containerd 成功!"
echo "============"
echo "============"
echo "开始重启 Containerd"
echo "============"
systemctl daemon-reload
systemctl enable containerd || handle_error "Containerd 执行 systemctl enable containerd 时失败"
systemctl restart containerd || handle_error "Containerd 执行 systemctl restart containerd 时失败"
echo "============"
echo "Containerd 重启成功!"
echo "============"
# 验证 /run/containerd/containerd.sock 是否存在
if [ ! -S /run/containerd/containerd.sock ]; then
handle_error "/run/containerd/containerd.sock Sock 文件不存在. Containerd 可能没有正确启动!!"
fi
}
configure_crictl() {
echo "============"
echo "开始配置 CriCtl"
echo "============"
CRICTL_CONFIG_FILE="/etc/crictl.yaml"
if [ -f "${CRICTL_CONFIG_FILE}" ]; then
cat >> "${CRICTL_CONFIG_FILE}" << EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: true
EOF
else
cat > "${CRICTL_CONFIG_FILE}" << EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: true
EOF
fi
echo "============"
echo "CriCtl 配置成功!"
echo "============"
echo "============"
echo "开始重启 Containerd"
echo "============"
sudo systemctl restart containerd || handle_error "Containerd 重启失败!"
echo "============"
echo "Containerd 重启成功!"
echo "============"
}
main() {
echo "============"
echo "开始执行脚本"
echo "============"
check_root
set_hostname "$1"
configure_time_sync
update_hosts
disable_swap
disable_firewalld
disable_selinux
configure_iptables
configure_docker
configure_containerd
configure_crictl
echo "============"
echo "脚本执行完成"
echo "============"
}
main "$@"
2. 通过 scp
发送到目标机器
scp prepare_kubernetes.sh root@192.168.105.132:/root
3. 赋予脚本执行权限
chmod +x prepare_kubernetes.sh
4. 运行脚本
sudo ./prepare_kubernetes.sh <hostname>
sudo ./prepare_kubernetes.sh k8s-master
sudo ./prepare_kubernetes.sh k8s-node1
sudo ./prepare_kubernetes.sh k8s-node2
三、初始化 Master 节点
3.1 查看版本
# 1. 查看 kubeadm 版本
kubeadm version
# 2. 查看 kubelet 版本
kubelet --version
# 3. 查看 kubectl 版本
kubectl version --client
3.2 生成默认配置文件
kubeadm config print init-defaults > kubeadm.yaml
3.3 修改默认配置文件
vim kubeadm.yaml
1. 修改 advertiseAddress: xxxx
为宿主机 IP
advertiseAddress: 192.168.105.132 # 修改为宿主机ip
2. 修改 nodeRegistration
中的 name
为宿主机名
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s-master
taints: null
3. 修改 imageRepository
为阿里云镜像
imageRepository: registry.aliyuncs.com/google_containers
4. 修改 kubernetesVersion
为 kubeadm
版本号
kubernetesVersion: 1.30.4 # kubeadm的版本为多少这里就修改为多少
5. 修改 networking
中的 podSubnet
值
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 ## 设置pod网段
6. 追加如下内容,关于 kubelet
的 CGroup
配置
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
3.4 下载所有镜像文件
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.30.4
3.5 开始进行初始化操作
kubeadm init --config kubeadm.yaml
3.6 将以上操作沉淀为脚本
1. 沉淀脚本,并命名为 init_kubernetes.sh
#!/bin/bash
set -e # 当有命令出错时,停止脚本的执行
# 全局变量
POD_SUBNET="10.244.0.0/16" # Pod 子网段
KUBERNETES_VERSION="1.30.4" # kubeadm 的版本号
MASTER_NODE_NAME="k8s-master" # 主节点的主机名
ADVERTISE_ADDRESS="192.168.105.132" # 主节点的 IP 地址
KUBEADM_CONFIG_FILE="kubeadm.yaml" # kubeadm 配置文件
IMAGE_REPOSITORY="registry.aliyuncs.com/google_containers" # 使用的镜像仓库
reset_kubernetes() {
echo "============"
echo "开始重置 Kubernetes"
echo "============"
kubeadm reset -f || handle_error "Failed to reset Kubernetes"
echo "============"
echo "重置 Kubernetes 成功!"
echo "============"
}
generate_default_config() {
echo "============"
echo "开始生成 默认的 kubeadm 配置文件"
echo "============"
kubeadm config print init-defaults > "$KUBEADM_CONFIG_FILE"
echo "============"
echo "默认的 kubeadm 配置文件生成成功!"
echo "============"
}
modify_config_file() {
echo "============"
echo "开始修改 默认的 kubeadm 配置文件"
echo "============"
# 修改 advertiseAddress
sed -i "s|^\(\s*advertiseAddress:\s*\).*|\1$ADVERTISE_ADDRESS|" "$KUBEADM_CONFIG_FILE"
# 修改 nodeRegistration 的 name
sed -i "s|^\(\s*name:\s*\).*|\1$MASTER_NODE_NAME|" "$KUBEADM_CONFIG_FILE"
# 修改 imageRepository
sed -i "s|^\(\s*imageRepository:\s*\).*|\1$IMAGE_REPOSITORY|" "$KUBEADM_CONFIG_FILE"
# 修改 kubernetesVersion
sed -i "s|^\(\s*kubernetesVersion:\s*\).*|\1$KUBERNETES_VERSION|" "$KUBEADM_CONFIG_FILE"
# 检查 networking 下是否有 podSubnet 属性
if ! grep -q "^\s*podSubnet:" "$KUBEADM_CONFIG_FILE"; then
# 如果没有 podSubnet 属性,添加它
sed -i "/^\s*networking:/a\ podSubnet: $POD_SUBNET" "$KUBEADM_CONFIG_FILE"
else
# 如果有 podSubnet 属性,修改它
sed -i "s|^\(\s*podSubnet:\s*\).*|\1$POD_SUBNET|" "$KUBEADM_CONFIG_FILE"
fi
# 追加 kubelet 的 CGroup 配置
cat >> "$KUBEADM_CONFIG_FILE" <<EOF
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
EOF
echo "============"
echo "修改 默认的 kubeadm 配置文件成功!"
echo "============"
}
pull_required_images() {
echo "============"
echo "开始下载所需的镜像文件"
echo "============"
kubeadm config images pull --image-repository="$IMAGE_REPOSITORY" --kubernetes-version="$KUBERNETES_VERSION"
echo "============"
echo "所需的镜像文件下载成功!"
echo "============"
}
initialize_master_node() {
echo "============"
echo "开始初始化 Kubernetes Master 节点"
echo "============"
kubeadm init --config "$KUBEADM_CONFIG_FILE"
echo "============"
echo "初始化 Kubernetes Master 节点成功!"
echo "============"
}
main() {
echo "============"
echo "开始执行脚本"
echo "============"
reset_kubernetes
generate_default_config
modify_config_file
pull_required_images
initialize_master_node
echo "============"
echo "开始执行完成"
echo "============"
}
main
2. 通过 scp
发送到目标机器
scp init_kubernetes.sh root@192.168.105.132:/root
3. 赋予脚本执行权限
chmod +x init_kubernetes.sh
4. 运行脚本
sudo ./init_kubernetes.sh
5. 出现下述输出,说明安装完成
3.7 初始化成功后运行命令
1. 按照控制台输出提示,在 Master
节点中执行上述图片中的命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 按照控制台输出提示,在
Master
节点中添加环境变量
# 设置环境变量
export KUBECONFIG=/etc/kubernetes/admin.conf
// 或者
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
3. 查看此时 Master
节点状态
kubectl get node
3.8 初始化成功后应用 Calico 网络插件
Calico
是 Kubernetes
中常用的网络插件之一。 Calico
适合需要高性能网络和高级网络策略的大型集群,适用于对网络安全和灵活性要求较高的场景。特点如下:
-
高性能:
Calico
使用基于路由的网络模式,不依赖覆盖网络,直接在主机网络上进行路由,性能较高。 -
网络策略:
Calico
支持Kubernetes
网络策略,可以实现细粒度的网络安全控制。 -
灵活性:
Calico
可以与多种数据平面(如BGP
、VXLAN
)集成,提供灵活的网络配置选项。 -
复杂性:由于功能强大,
Calico
的配置和管理相对复杂,适合有一定经验的用户。
Kubernetes
应用 Calico
网络插件的操作如下:
1. 下载 Calico
网络插件: 在 M1 Mac
上下载 calico.yaml
配置文件,并传输到 VMFunction Centos8 ARM 64
。
# 1. M1 Mac 获取下载地址
浏览器访问 https://docs.projectcalico.org/manifests/calico.yaml 会发生重定向,复制重定向之后的地址
# 2. M1 Mac 下载 calico.yaml
curl -O https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml
# 3. M1 Mac 传输到 VMFunciton Centos8 ARM 64
scp calico.yaml root@192.168.105.132:/root
# 4. VMFunciton Centos8 ARM 64 移动 calico.yaml 到 /tmp 目录下
mv calico.yaml /tmp
2. 查看 Calico
配置文件 /tmp/calico.yaml
依赖镜像: 在 /tmp/calico.yaml
中搜索 image
关键词即可
cat /tmp/calico.yaml
- name: upgrade-ipam
image: docker.io/calico/cni:v3.25.0
imagePullPolicy: IfNotPresent
- name: calico-node
image: docker.io/calico/node:v3.25.0
imagePullPolicy: IfNotPresent
containers:
- name: calico-kube-controllers
image: docker.io/calico/kube-controllers:v3.25.0
imagePullPolicy: IfNotPresent
3. 下载并上传所需镜像: 在可科学上网的机器上下载 arm64
镜像,并上传到阿里云个人镜像仓库。
# cni
docker pull --platform linux/arm64 docker.io/calico/cni:v3.25.0
docker inspect calico/cni:v3.25.0 | grep Architecture
docker tag calico/cni:v3.25.0 registry.cn-hangzhou.aliyuncs.com/bolawen/calico-cni:v3.25.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/calico-cni:v3.25.0-linux-arm64
# node
docker pull --platform linux/arm64 docker.io/calico/node:v3.25.0
docker inspect calico/node:v3.25.0 | grep Architecture
docker tag calico/node:v3.25.0 registry.cn-hangzhou.aliyuncs.com/bolawen/calico-node:v3.25.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/calico-node:v3.25.0-linux-arm64
# kube-controllers
docker pull --platform linux/arm64 docker.io/calico/kube-controllers:v3.25.0
docker inspect calico/kube-controllers:v3.25.0 | grep Architecture
docker tag calico/kube-controllers:v3.25.0 registry.cn-hangzhou.aliyuncs.com/bolawen/calico-kube-controllers:v3.25.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/calico-kube-controllers:v3.25.0-linux-arm64
4. 配置 /tmp/calico.yaml
sed -i -e 's|docker.io/calico/cni:v3.25.0|registry.cn-hangzhou.aliyuncs.com/bolawen/calico-cni:v3.25.0-linux-arm64|g' \
-e 's|docker.io/calico/node:v3.25.0|registry.cn-hangzhou.aliyuncs.com/bolawen/calico-node:v3.25.0-linux-arm64|g' \
-e 's|docker.io/calico/kube-controllers:v3.25.0|registry.cn-hangzhou.aliyuncs.com/bolawen/calico-kube-controllers:v3.25.0-linux-arm64|g' /tmp/calico.yaml
5. 应用 calico.yml
配置
# 如果之前未安装过 Calico
sudo kubectl apply -f /tmp/calico.yaml
# 如果之前已经安装过 Calico
sudo kubectl delete -f /tmp/calico.yaml
sudo kubectl apply -f /tmp/calico.yaml
6. 验证 calico
网络插件
# 查看 calico 各个服务状态
kubectl get pods --namespace kube-system
# 查看 calico-xxx Pod 的日志
kubectl logs --namespace kube-system <pod-name>
# 查看 calico-xxx Pod 的详细描述
kubectl describe pod <pod-name> --namespace kube-system
看到如下信息时,说明安装成功!
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-xxxxxx-xxxxx 1/1 Running 0 1m
calico-node-xxxxxx-xxxxx 1/1 Running 0 1m
7. 查看此时 Master
节点状态
kubectl get node
3.9 初始化成功后部署 Dashborard 仪表盘
Dashboard
是基于网页的 Kubernetes
用户界面。 你可以使用 Dashboard
将容器应用部署到 Kubernetes
集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard
获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes
资源 (如 Deployment
、Job
、DaemonSet
等等)。 例如,你可以对 Deployment
实现弹性伸缩、发起滚动升级、重启 Pod
或者使用向导创建新的应用。Dashboard
同时展示了 Kubernetes
集群中的资源状态信息和所有报错信息。Dashboard
安装部署如下:
1. 安装 Helm
包管理器: Helm 是 Kubernetes
的包管理器。在 M1 Mac
和 VMFunction Centos8 ARM 64
分别安装 Helm
。M1 Mac
只需要通过 brew
的形式安装即可,VMFunction Centos8 ARM 64
需要在 M1 Mac
上下载 get_helm.sh
然后传输到 VMFunction Centos8 ARM 64
中。
# 1. M1 Mac 安装 Helm
brew install helm
# 2. M1 Mac 测试 Helm
heml version
helm repo list
# 3. M1 Mac 下载 get_helm.sh
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
# 4. M1 Mac 将 get_helm.sh 传输到 VMFunciton Centos8 ARM 64
scp get_helm.sh root@192.168.105.135:/root
# 5. VMFunciton Centos8 ARM 64 执行如下命令
chmod 700 get_helm.sh
sudo ./get_helm.sh
# 6. VMFunciton Centos8 ARM 64 测试 helm
heml version
helm repo list
2. 下载 Dashboard
安装包并生成 values.yaml
配置文件: 在 M1 Mac
上基于 helm
下载 kubernetes-dashboard 的 .tgz
文件。然后在 M1 Mac
上使用 helm
生成 values.yaml
配置文件,最后将 kubernetes-dashboard.tgz
和 values.yaml
全部传输到 VMFunction Centos8 ARM 64
。
# 1. M1 Mac helm 添加 kubernetes-dashboard 仓库
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm repo list
# 2. M1 Mac helm 下载 kubernetes-dashboard.tgz
helm fetch kubernetes-dashboard/kubernetes-dashboard
# 3. M1 Mac 通过 helm 生成 values.yaml 配置文件
helm show values kubernetes-dashboard/kubernetes-dashboard > values.yaml
# 4. M1 Mac 将 values.yaml 传输到 VMFunciton Centos8 ARM 64
scp values.yaml root@192.168.105.132:/root
# 5. M1 Mac 将 kubernetes-dashboard-7.5.0.tgz 传输到 VMFunciton Centos8 ARM 64
scp kubernetes-dashboard-7.5.0.tgz root@192.168.105.132:/root
3. 查看 Dashboard
配置文件 values.yaml
依赖镜像: 在 values.yaml
中搜索 image
关键词即可
cat values.yaml
auth:
role: auth
image:
repository: docker.io/kubernetesui/dashboard-auth
tag: 1.1.3
api:
role: api
image:
repository: docker.io/kubernetesui/dashboard-api
tag: 1.7.0
web:
role: web
image:
repository: docker.io/kubernetesui/dashboard-web
tag: 1.4.0
metricsScraper:
enabled: true
role: metrics-scraper
image:
repository: docker.io/kubernetesui/dashboard-metrics-scraper
tag: 1.1.1
# 隐藏的一个镜像
docker.io/library/kong:3.6
4. 查看 kubernetes-dashboard/charts/kong/values.yaml
依赖镜像: 在 M1 Mac
上解压 kubernetes-dashboard-7.5.0.tgz
,查看 kubernetes-dashboard/charts/kong/values.yaml
文件中的依赖镜像。该文件包含两个需要下载的镜像。
# 1. M1 Mac 解压 kubernetes-dashboard-7.5.0.tgz
tar -zxvf kubernetes-dashboard-7.5.0.tgz
# 2. M1 Mac 查看 kubernetes-dashboard/charts/kong/values.yaml 依赖镜像
code kubernetes-dashboard/charts/kong/values.yaml
image:
repository: kong
tag: "3.6"
ingressController:
enabled: true
image:
repository: kong/kubernetes-ingress-controller
tag: "3.1"
5. 下载并上传所需镜像: 在可科学上网的机器上下载 arm64
镜像,并上传到阿里云个人镜像仓库。
# dashboard-auth:1.1.3
docker pull --platform linux/arm64 docker.io/kubernetesui/dashboard-auth:1.1.3
docker inspect kubernetesui/dashboard-auth:1.1.3 | grep Architecture
docker tag kubernetesui/dashboard-auth:1.1.3 registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-auth:1.1.3-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-auth:1.1.3-linux-arm64
# dashboard-api:1.7.0
docker pull --platform linux/arm64 docker.io/kubernetesui/dashboard-api:1.7.0
docker inspect kubernetesui/dashboard-api:1.7.0 | grep Architecture
docker tag kubernetesui/dashboard-api:1.7.0 registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-api:1.7.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-api:1.7.0-linux-arm64
# dashboard-web:1.4.0
docker pull --platform linux/arm64 docker.io/kubernetesui/dashboard-web:1.4.0
docker inspect kubernetesui/kubernetesui/dashboard-web:1.4.0 | grep Architecture
docker tag kubernetesui/dashboard-web:1.4.0 registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-web:1.4.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-web:1.4.0-linux-arm64
# dashboard-metrics-scraper:1.1.1
docker pull --platform linux/arm64 docker.io/kubernetesui/dashboard-metrics-scraper:1.1.1
docker inspect kubernetesui/kubernetesui/dashboard-metrics-scraper:1.1.1 | grep Architecture
docker tag kubernetesui/dashboard-metrics-scraper:1.1.1 registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-metrics-scraper:1.1.1-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/dashboard-metrics-scraper:1.1.1-linux-arm64
# kong:3.6
docker pull --platform linux/arm64 docker.io/library/kong:3.6
docker tag docker.io/library/kong:3.6 registry.cn-hangzhou.aliyuncs.com/bolawen/kong:3.6-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/kong:3.6-linux-arm64
# kong/kubernetes-ingress-controller:3.1
docker pull --platform linux/arm64 kong/kubernetes-ingress-controller:3.1.0
docker tag kong/kubernetes-ingress-controller:3.1.0 registry.cn-hangzhou.aliyuncs.com/bolawen/kong-kubernetes-ingress-controller:3.1.0-linux-arm64
docker push registry.cn-hangzhou.aliyuncs.com/bolawen/kong-kubernetes-ingress-controller:3.1.0-linux-arm64
6. 配置 values.yaml
: 将 image.repository
和 image.tag
替换为阿里云上的镜像地址和 arm64
版本。
# VMFunciton Centos8 ARM 64
sed -i -e 's|docker.io/kubernetesui|registry.cn-hangzhou.aliyuncs.com/bolawen|g' \
-e 's|tag: 1.1.3|tag: 1.1.3-linux-arm64|g' \
-e 's|tag: 1.7.0|tag: 1.7.0-linux-arm64|g' \
-e 's|tag: 1.4.0|tag: 1.4.0-linux-arm64|g' \
-e 's|tag: 1.1.1|tag: 1.1.1-linux-arm64|g' values.yaml
7. 配置 kubernetes-dashboard/charts/kong/values.yaml
: 将 image.repository
和 image.tag
替换为阿里云上的镜像地址和 arm64
版本。
# M1 Mac
sed -i '' -e 's|repository: kong|repository: registry.cn-hangzhou.aliyuncs.com/bolawen/kong|g' \
-e 's|repository: kong/kubernetes-ingress-controller$|repository: registry.cn-hangzhou.aliyuncs.com/bolawen/ kong-kubernetes-ingress-controller|g' \
-e 's|tag: "3.6"|tag: "3.6-linux-arm64"|g' \
-e 's|tag: "3.1"|tag: "3.1:3.1.0-linux-arm64"|g' kubernetes-dashboard/charts/kong/values.yaml
8. 重新打包 kubernetes-dashboard-7.5.0.tgz
: M1 Mac
上重新将 kubernetes-dashboard
打包为 kubernetes-dashboard-7.5.0.tgz
, 并传输到 VMFunction Centos8 ARM 64
# 1. 重新打包 kubernetes-dashboard-7.5.0.tgz
tar -zcvf kubernetes-dashboard-7.5.0.tgz kubernetes-dashboard/
# 2. M1 Mac 传输到 VMFunction Centos8 ARM 64
scp kubernetes-dashboard-7.5.0.tgz root@192.168.105.132:/root
9. 通过 Helm
安装部署 Dashborard
# 如果之前未安装过
helm upgrade --install kubernetes-dashboard kubernetes-dashboard-7.5.0.tgz --create-namespace --namespace kubernetes-dashboard -f values.yaml
# 如果之前已经安装过
helm uninstall kubernetes-dashboard --namespace kubernetes-dashboard
helm list --namespace kubernetes-dashboard
helm upgrade --install kubernetes-dashboard kubernetes-dashboard-7.5.0.tgz --create-namespace --namespace kubernetes-dashboard -f values.yaml
10. 验证 Dashborard
状态
# 查看 kubernetes-dashboard 各个服务状态
kubectl get svc --namespace kubernetes-dashboard
kubectl get pods --namespace kubernetes-dashboard
# 查看 kubernetes-dashboard-xxx Pod 的日志
kubectl logs --namespace kubernetes-dashboard <pod-name>
# 查看 kubernetes-dashboard-xxx Pod 的详细描述
kubectl describe pod --namespace kubernetes-dashboard <pod-name>
# 检测 kubernetes-dashboard 的资源配置(如 CPU 和内存)足够
kubectl get pod <pod-name> -n kubernetes-dashboard -o yaml
11. 编辑 Dashborard
各个组件
# 查看 kubernetes-dashboard 各个组件服务
kubectl get svc --namespace kubernetes-dashboard
# 编辑 kubernetes-dashboard 各个组件服务
kubectl edit svc kubernetes-dashboard-api --namespace kubernetes-dashboard // 编辑 TYPE 为 NodePort
kubectl edit svc kubernetes-dashboard-auth --namespace kubernetes-dashboard // 编辑 TYPE 为 NodePort
kubectl edit svc kubernetes-dashboard-kong-manager --namespace kubernetes-dashboard // 编辑 TYPE 为 NodePort
……
kubectl edit svc kubernetes-dashboard-web --namespace kubernetes-dashboard // 编辑 TYPE 为 NodePort
# 再次查看 kubernetes-dashboard 各个组件服务
kubectl get svc --namespace kubernetes-dashboard
12. 创建 Dashborard
用户: Dashborard 用户文档地址
# 创建 dashboard-adminuser.yaml 文件
vim dashboard-adminuser.yaml
# dashboard-adminuser.yaml 文件内容
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
name: admin-user
namespace: kubernetes-dashboard
annotations:
kubernetes.io/service-account.name: "admin-user"
type: kubernetes.io/service-account-token
13. 应用 dashboard-adminuser.yaml
配置
kubectl apply -f dashboard-adminuser.yaml
14. 获取 Dashborard
Token
kubectl -n kubernetes-dashboard create token admin-user
15. 访问 Dashborard
: 本文是 M1 Mac + VMFunciton Centos8 ARM 64
, 在 VMFunciton Centos8 ARM 64
上部署 Kubernetes Dashboard
, 经过 kubectl edit svc
编辑 Kubernetes Dashboard
各个组件 Type
为 NodePort
。然后在 M1 Mac
上进行访问, 访问地址如下:
# 格式
http://VMFunciton Centos8 ARM 64 IP地址:kubernetes-dashboard-web Port
# 举例
http://192.168.105.132:31008
四、初始化 Worker 节点
4.1 Workder 节点加入 Master 集群
在 Worker
节点上, 基于 kubeadm join
加入 Master
节点集群: 如果不小心把 kubeadm join
命令清屏了,使用:kubeadm token create --print-join-command
重新生成
kubeadm join 192.168.105.132:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:e34da279d1bc8dd0ef0ee8f4c3f934865e79fa489b9ee45b409ce3794de728b5
4.2 验证 Wroker 节点与 Master 集群
在 Master
节点上,通过 kubectl get nodes
查看 Worker
节点状态
kubectl get nodes
或者
kubectl get pod -A
或者
kubectl get pods -n kube-system