掘金 后端 ( ) • 2024-03-28 16:18

部署生产就绪的Kubernetes集群需要考虑到管理、负载均衡、安全、存储等很多细节,本文给出了一个生产就绪Kubernetes集群的完整部署流程,可以作为生产部署的有效参考。原文: Deploying a Production Kubernetes Cluster in 2023 — A Complete Guide

Growtika @Unsplash

最近有一些文章提到,Kubernetes 作为平台可能正在失去人气,有些人甚至认为该平台已经死亡或即将死亡。对这种观点我坚决持反对意见,Kubernetes 仍然非常重要,并被广泛采用,并且 Kubernetes 最近还取得了一些令人兴奋的进步和更新。

事不宜迟,让我们开始吧。本文将逐步介绍如何部署一个可在企业内部、大型数据中心或云上运行的生产就绪型 Kubernetes 集群。(或者三者同时兼得!)。

该集群将重点关注几个关键问题:

  • 易于部署
  • 易于管理
  • 从负载均衡器到 etcd 集群,每一层都具有可扩展性,加入新节点所需的步骤最少
  • 安全性 - 每个节点之间的每个连接都经过加密
  • 开箱即用 - 本文结束时,无需其他配置,就可以保证从高可用控制平面到群集文件系统一切正常运行。

我们首先了解一下部署环境:

  • 该集群不适用于单板计算机(Raspberry Pi 等)。集群需要相当大的空间、内存和 CPU。(但没有什么是单个 ESX 或 Hyper-V 节点无法处理的)。
  • etcd 喜欢固态硬盘,但并非必需,除非需要运行大型、I/O 密集的 etcd 集群。
  • 在这种部署场景中,不仅可以混合/匹配不同的 Worker/控制平面节点类型,还可以混合和匹配部署环境。这意味着,既可以在一台服务器上部署 Worker,也可以在桌面上部署测试 Worker,或者在 Azure 中部署 HA 控制平面,甚至在 AWS 中部署镜像。是的,就应该有这么大的灵活性。
  • 该设置在 ESX 企业环境中使用非 SSD 存储器进行了测试。
  • 根据 vCenter 中的资源池统计数据,仅在运行管理工作负载时,整个群集都在使用资源池:
    • 10 台虚拟机 + 负载均衡器(可以是另一台虚拟机)
    • 每个节点平均 ~300-500 MB 内存
    • 每个节点的 CPU 平均频率为 ~500-700 MHz
    • etcd 使用了 50 GB 硬盘,master 使用了 80 GB 硬盘,worker 使用了 120 GB 硬盘

让我们看看集群中到底有什么。

整个集群按生产就绪规格部署,包括 10 台虚拟机和一个负载均衡器,这显然是一个大型集群,旨在处理大型企业级工作负载,并可进一步扩展。

如果需要缩小规模,可以使用 2 个 etcd 节点(至少 1 个主节点和 1 个 Worker 节点),外加一个负载均衡器虚拟机,该虚拟机还可以在需要时处理存储(或者存储可以来自 NAS / SAN)。

ETCD 集群:

3 节点 etcd 集群是分布式键值数据库引擎,被用作 Kubernetes 集群的键值数据库。用 Kubernetes 术语来说,etcd 就是 "后端数据存储"。集群具有高可用性,所有连接都通过负载均衡器(在本部署中为 HAProxy)路由。所有连接都基于证书进行加密和保护。在此部署中,我们将关闭捆绑的 etcd 服务,而只使用外部群集。

负载均衡器:

负载均衡器是群集的外部组件,负责处理多个事物之间的连接:

  • etcd 节点间连接
  • 连接到 etcd 集群(+ 负载均衡)
  • 主节点到主节点的连接
  • 与控制平面(master)集群的连接(+ 负载均衡)
  • 工作节点与主集群之间的通信(+ 负载均衡)
  • 可选--从用户到 Kubernetes 工作负载的会话和 TLS 终止(如果不使用ingress)(+ 负载均衡)

存储:

可以是任何拥有大量可用磁盘空间并能处理 iSCSI 连接的设备。(或任何你想用来将设备上的存储空间提供给群集节点的技术)。在本部署中,使用运行 iSCSI 服务器的虚拟机,该服务器使用 ESX 管理的数据存储空间。在本场景中也可以使用企业级 NAS 或 SAN。

主集群:

3 个主节点运行 Kubernetes 控制平面和所有其他主服务,Kubernetes 工作节点连接到这个主集群。需要注意的是,主集群也能托管 Kubernetes 工作负载(在较大的数据中心规模集群中通常不会这么做)。

工作节点:

Worker 通过负载均衡器连接到主集群,承载大部分 Kubernetes 工作负载。在此部署中,主集群和 Worker 都能运行工作负载。请注意,工作节点不是集群,而是连接到主群集的独立服务器。

OCFS2 集群文件系统存储集群:

主节点和工作节点托管分布式 Oracle 集群文件系统存储集群,为我们提供共享的集群就绪存储。可以在这里使用任何集群感知的文件系统,但我决定使用 OCFS2,因为它是企业级的,而且设置简单。

除 etcd 节点和负载均衡器外,每个节点都将有一个共享磁盘,包含一个 OCFS2 集群文件系统,该系统将由 Longhorn 管理,并拥有自己的存储类。

集群看起来如下所示(注意,在本次部署中,我们将使用 ETCD 的负载均衡器):


准备服务器

如前所述,整个部署包括 10 台服务器或虚拟机,或两者的某种组合。有关所需的最少机器数量,请参阅上文。

在部署过程中,使用 Ubuntu 22.04 最小化版本。请注意,"最小化"部分仅仅意味着安装程序除了运行 Ubuntu 所需的绝对最低限度的内容外,不会安装任何其他内容。这可以在 Ubuntu 引导安装程序中选择。还要注意的是,所有机器都没有图形用户界面。

我们不用 kubectl 代理,因为这是个需要被淘汰的糟糕工具,而且我们也不会使用任何localhost地址。所以不要使用图形用户界面!建议在每台机器上安装非 GUI 版本的 Linux,拥抱终端!

我在上面公布了每种虚拟机类型的平均计算基准,需要根据用途规划部署。在我的部署中,将其用于中等强度的生产工作负载,因此在每台服务器上配备了 8 到 12 GB 的内存,每个虚拟机也有 12 个 vCPU。但还是那句话,根据你认为适合的使用情况来调整。

在我的部署中,共享集群卷也有大约 500 GB 的空间。

一旦 10 台服务器或你选择部署的任何数量的机器安装完毕,就比较好玩了!

在每台机器上运行常规准备指令。

apt update && apt upgrade -y

更新完成后,请确保以下事项。这一点非常重要!

  • 每台服务器/虚拟机必须有唯一的主机名。不要使用服务器 1 或节点 a 这样的名称。
  • 每个主机名都必须能够访问其他每个主机名。如果有内部 DNS 系统或可信任的任何 DNS 解决方案,请为每个服务器的主机名创建 A 记录。
  • 不过建议使用 /etc/hosts 文件并复制/粘贴整个集群(所有负载均衡器、所有主服务器、所有 Worker、存储服务器和所有 etcd 节点)中的主机名和 IP 列表,将其复制到每台参与部署的服务器上。

在本指南中,我们将使用 nano 文本编辑器编辑内容。

准备服务器的一些有用命令:

1a. 更改主机名:

sudo hostname new-hostname

1b. 编辑主机文件:

sudo nano /etc/hosts

1c. 如果更改了主机名,请确保更新主机文件中的主机名。全部完成后,重启服务器。

题外话--如果不想每次都连接 10 台服务器,可以使用 Terminus 等程序或 Ansible / AWX 等命令系统。

  1. 交换区仍然会破坏容器编排系统。除了存储系统、etcd 和负载均衡器,我们可以关闭其他节点的交换区。

在任何托管 Kubernetes 的节点上(仅限主节点和工作节点):

sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

以及:

sudo swapoff -a
  1. 还需要更改 Linux 网络方面的一些内容。在任何托管 Kubernetes 的节点上运行一下指令(仅限主节点和工作节点):
sudo modprobe overlay
sudo modprobe br_netfilter

sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

准备工作到此为止。(真的就是这样,K3S 会为我们进行实际安装)


我们把 Kubernetes 节点先放在一边,研究负载均衡器。

通过 SSH 登录负载均衡器,并运行以下命令:

  1. 更新源代码并安装 HAProxy。
apt update && apt install haproxy -y
  1. 创建包含以下内容的配置文件:
  • 用于 etcd 集群通信的前端
  • 主集群通信前端
  • HAProxy 统计前端
  • 用于 etcd 集群通信的后端
  • 主集群通信后台

配置如下所示,请修改绑定和 IP,使其与网络相匹配。

nano /etc/haproxy/haproxy.cfg
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        daemon

stats socket /var/lib/haproxy/stats # Make sure this path / file exists

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend stats
        bind *:8399
        stats enable
        stats uri /stats_secure
        stats refresh 10s
        stats admin if LOCALHOST
        stats auth some_user:changeme # Change to your desired logins

frontend etcha200-main # For ETCD
        bind 10.0.1.5:2379 # Change to your network
        retries 3
        mode tcp
        option tcplog
        default_backend etcha200-main-backend


frontend kubeha200lb # For master cluster
        bind 10.0.1.5:6443 # Change to your network
        retries 3
        mode tcp
        option tcplog
        default_backend kubha200-masters


backend etcha200-main-backend
        mode tcp
        balance roundrobin
        option tcp-check

        server etc020 server_ip_address:2379 check fall 3 rise 2 # Change to your ETCD servers
        server etc021 server_ip_address:2379 check fall 3 rise 2
        server etc022 server_ip_address:2379 check fall 3 rise 2


backend kubha200-masters
        mode tcp
        balance roundrobin
        option httpchk GET /healthz
        http-check expect status 200    # Expect a 200 OK response for a healthy server
        timeout connect 5s       # Increase the timeout for establishing connections
        timeout server 60s       # Increase the timeout for waiting for a response from the server
        timeout check 10s        # Increase the timeout for health checks
        option tcp-check

        server kubema050 server_ip_address:6443 check fall 3 rise 2 # Change to your master servers
        server kubema051 server_ip_address:6443 check fall 3 rise 2
        server kubema052 server_ip_address:6443 check fall 3 rise 2
  1. 编辑文件后,保存并重启 HAProxy:
sudo systemctl restart haproxy
sudo systemctl enable haproxy
  1. 现在,你就有了一个完全配置好的 HAProxy 负载均衡器,还可以通过以下网址访问 HAProxy 面板:

http://<haproxy服务器ip>:8399

登录名设置在配置文件开头。

但是,但是,但是,我的 HAProxy 没有启动!

如果在编写配置后启动 HAproxy 时遇到问题,请检查以下事项:

  • 绑定的 IP 是否在该服务器上可用?(它们必须是分配给该服务器上网络适配器的一个或多个 IP)。
  • 每个前端都有匹配的后端吗?
  • 是否创建了socket或者admin.sock文件?如果没有,请创建。
  • 确保文件中没有错别字。
  • 要检查 HAProxy 配置,请执行:
haproxy -f /etc/haproxy/haproxy.cfg -c

有关 HAProxy 或其他故障排除指南的更多详情,请参阅:https://www.haproxy.com/blog/testing-your-haproxy-configuration

还要注意的是,当集群建立后, HAProxy 服务器将处理一些非常重要的连接。可能需要考虑设置高可用 HAProxy,始终通过上述命令验证更改,并使用 haproxy reload 代替 haproxy restart。

负载均衡器就这些东西!


现在,我们来构建可投入生产的 etcd 集群。

  1. 以 SSH 方式登录每个 etcd 节点并运行以下命令:
nano download-etcd.sh
  1. 复制并粘贴此脚本:
#!/bin/bash

ETCD_VER="v3.5.9"
DOWNLOAD_URL="https://storage.googleapis.com/etcd"

# Clean up previous downloads
rm -f "/tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz"
rm -rf "/tmp/etcd-download-test"
mkdir -p "/tmp/etcd-download-test"

# Download etcd release
curl -L "${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz" -o "/tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz"

# Extract and prepare downloaded files
tar xzvf "/tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz" -C "/tmp/etcd-download-test" --strip-components=1

# Clean up downloaded tarball
rm -f "/tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz"

# Make binaries executable
chmod +x "/tmp/etcd-download-test/etcd"
chmod +x "/tmp/etcd-download-test/etcdctl"

# Verify the downloaded binaries
"/tmp/etcd-download-test/etcd" --version
"/tmp/etcd-download-test/etcdctl" version

# Move binaries to the bin folder
sudo mv "/tmp/etcd-download-test/etcd" "/usr/local/bin"
sudo mv "/tmp/etcd-download-test/etcdctl" "/usr/local/bin"

echo "etcd ${ETCD_VER} is now installed and ready for use."
  1. 保存并使其可执行:
chmod 766 download-etcd.sh
  1. 运行下载脚本:
./download-etcd.sh

脚本将自动下载并安装最新版本的 etcd。在撰写本文时,该版本为 3.5.9。

  1. 确保安装了etcd:
etcd --version

etcd Version: 3.5.9
Git SHA: c92fb80f3
Go Version: go1.19.10
Go OS/Arch: linux/amd64
  1. 现在需要制作证书。本文使用了 Cloud Flare 的 SSL 工具。你可以随意使用任何工具,只需为集群中的每个节点创建一个 CA 文件、一个 .crt 和一个 .key。

安装 cfssl:

VERSION=$(curl --silent "https://api.github.com/repos/cloudflare/cfssl/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
VNUMBER=${VERSION#"v"}

wget https://github.com/cloudflare/cfssl/releases/download/${VERSION}/cfssl_${VNUMBER}_linux_amd64 -O cfssl

chmod +x cfssl

sudo mv cfssl /usr/local/bin

注意--本文将在第一个 etcd 节点上安装 cfssl,但在哪里安装和生成证书并无区别,可以在任何 Linux 或 Mac 机器上进行安装。

如果需要其他 cfssl 安装说明:https://computingforgeeks.com/how-to-install-cloudflare-cfssl-on-linux-macos/?expand_article=1

  1. 接下来需要生成证书。
mkdir certs && cd certs
echo '{"CN":"CA","key":{"algo":"rsa","size":2048}}' | cfssl gencert -initca - | cfssljson -bare ca -
echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","server auth","client auth"]}}}' > ca-config.json

这将创建目录结构并设置证书生成器配置。

创建 3 个文件 - ca-key.pemca.pemca.csr

  1. 接下来,我们需要创建实际的证书和密钥:

重要!确保将主机名和 IP 替换为自己的主机名和 IP,并且必须与之前创建的主机文件或 DNS 记录相匹配。

export NAME=etcd-1
export ADDRESS=10.0.1.15,$NAME
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME

做一次 ls,看看目前有什么:

ls

现在我们应该有了第一个节点的证书和密钥。

  1. 在每个 etcd 节点上重复上述步骤,为负载均衡器创建证书,需要更改的只是 IP 和名称。

完成上述工作后,就可以为每个 etcd 节点和 HAProxy 节点获得一整套证书和密钥。请确保将其保存在安全的地方!

  1. 现在,需要将证书和密钥分发到每个节点。
Server=10.0.0.16
USER=somebody
 
scp ca.pem $USER@$HOST:etcd-ca.crt
scp node-1.pem $USER@$HOST:server.crt
scp node-1-key.pem $USER@$HOST:server.key

用你自己的服务器和用户以及证书名称替换服务器和用户。请注意,由于需要复制大量文件,可能需要花费一段时间。

如果想使用图形用户界面来传输文件,也可以使用 Cyberduck 这样的程序。

请注意文件名和扩展名!确保每台 etcd 服务器和负载均衡器上都有 2 个 .crt 和 1 个 .key。

  1. 现在,用 ssh 登录复制了证书的每个节点,并将它们移到一个合适的目录下。我用的是 /etc/pki/k3s。
sudo mkdir -p /etc/pki/k3s
sudo mv * /etc/pki/k3s
sudo chmod 600 /etc/pki/k3s/server.key
  1. 现在我们已经生成了证书,并将其放置在正确的位置,好戏才刚刚开始。现在我们可以开始安装 etcd,但不会基于官方手册,而是用负载均衡器,确保所有节点之间的通信安全,避免使用临时连接。
sudo nano /etc/etcd/etcd.conf

粘贴以下内容并根据注释进行修改:

ETCD_NAME=hostname # 更改为当前ETCD节点的主机名
ETCD_LISTEN_PEER_URLS="https://server_ip:2380" # 修改为当前ETCD节点的IP
ETCD_LISTEN_CLIENT_URLS="https://server_ip:2379" # 修改为当前ETCD节点的IP
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" # 任何你想用的名字,没有空格
ETCD_INITIAL_CLUSTER="etcd1=https://server_ip_1:2380,etcd2=https://server_ip_2:2380,etcd3=https://server_ip_3:2380" # 所有ETCD集群成员主机名和IP
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://server_ip:2380" # 当前节点IP
ETCD_ADVERTISE_CLIENT_URLS="https://haproxy:2379" # 负载均衡器的主机名 (不是IP)
ETCD_TRUSTED_CA_FILE="/etc/pki/etcd/etcd-ca.crt" # 确保所有路径都是正确的
ETCD_CERT_FILE="/etc/pki/etcd/server.crt"
ETCD_KEY_FILE="/etc/pki/etcd/server.key"
ETCD_PEER_CLIENT_CERT_AUTH=true
ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/etcd-ca.crt"
ETCD_PEER_KEY_FILE="/etc/etcd/server.key"
ETCD_PEER_CERT_FILE="/etc/etcd/server.crt"
ETCD_DATA_DIR="/var/lib/etcd"

请务必仔细检查主机名和 IP。如果稍后出现故障,请先检查该文件是否有误。

  1. 对每个 etcd 节点执行与步骤 12 相同的步骤。确保根据需要更改节点 IP 和主机名。

  2. 接下来,我们将创建单元文件。

sudo nano /lib/systemd/system/etcd.service

粘贴以下内容:

[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target
 
[Service]
Type=notify
EnvironmentFile=/etc/etcd/etcd.conf
ExecStart=/usr/local/bin/etcd
Restart=always
RestartSec=10s
LimitNOFILE=40000
 
[Install]
WantedBy=multi-user.target

在所有 etcd 节点上执行相同操作。

  1. 准备启动 etcd 服务!
sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd

此时,etcd 服务应在所有 etcd 节点上运行。检查一下状态:

sudo systemctl status etcd

应该显示服务已加载并运行,而且不应该出现任何错误。

如果出现节点未加入或服务无法启动的错误:

  • 查看 etcd 日志。如果服务启动失败,查看journal日志和服务日志。
  • 仔细检查单元文件和 etcd.conf 文件。
  • 确保证书路径正确,且可被 etcd 写入。
  • 检查 etcd 后端和前端的 HAProxy 配置。
  1. 此步骤为可选步骤。如果要测试 etcd 群集的功能,可以使用以下命令:
curl --cacert /etc/pki/k3s/etcd-ca.crt --cert /etc/pki/k3s/server.crt --key /etc/pki/k3s/server.key https://haproxy:2379/health

将证书路径和 HAProxy 主机名替换为自己的,这条命令可以检查集群健康状况。

etcdctl --endpoints https://haproxy:2379 --cert /etc/etcd/server.crt --cacert /etc/etcd/etcd-ca.crt --key /etc/etcd/server.key member list
etcdctl --endpoints https://haproxy:2379 --cert /etc/etcd/server.crt --cacert /etc/etcd/etcd-ca.crt --key /etc/etcd/server.key remove foo bar
etcdctl --endpoints https://haproxy:2379 --cert /etc/etcd/server.crt --cacert /etc/etcd/etcd-ca.crt --key /etc/etcd/server.key put foo bar
etcdctl --endpoints https://haproxy:2379 --cert /etc/etcd/server.crt --cacert /etc/etcd/etcd-ca.crt --key /etc/etcd/server.key del foo

请再次将证书路径和 HAProxy 主机名替换为自己的路径和主机名。这是为了测试在数据库中存储、获取和删除对象。

还可以使用第一条命令查看成员列表,以确保所有节点都在。

如果测试一切正常,那么恭喜你,现在有了一个安全、高可用的 etcd 集群,可以随时接受来自 Kubernetes 的连接。


现在,我们已经为 Kubernetes 设置了所有基础设施服务,可以设置实际的 K3S 集群了。

我们先从master开始。

  1. 确保在所有主节点上禁用交换区(如前所述),完成网络部分设置。
  2. 确保主机文件和/或 DNS 与集群中的所有主机名一致。
  3. 确保已按照虚拟机准备步骤所述,将证书、密钥和 ca 文件复制到每个主服务器上。
  4. 出发!

这是我们用来安装 K3S 服务并将节点设置为主节点的命令:

curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s - server   --token=your_token   --datastore-endpoint="https://haproxy:2379"   --datastore-cafile="/etc/pki/k3s/etcd-ca.crt"   --datastore-certfile="/etc/pki/kube/server.crt"   --datastore-keyfile="/etc/pki/k3s/server.key"   --tls-san=haproxy

确保将参数替换为你自己的参数。

下面是这条命令的作用:

  • 该命令是一条 curl 命令
  • 获取实际安装程序
  • 设置配置模式。详见最后的配置选项链接。
  • 我们想让这个节点成为 "sever",也就是主节点。
  • 令牌是生成的字符串,建议只使用字母和数字,长度不超过 32 个字符,确保安全。
  • 数据存储端点参数告诉 K3S 安装程序使用 etcd 群集,而不是将 etcd 作为工作负载部署。
  • 接下来是证书文件路径,需要使用为负载均衡器生成的证书,确保使用主机名。
  • tls-san 是负载均衡器的主机名。

一切就绪后,运行命令。

命令需要几分钟时间执行。如果一切正常,命令进程将随着 K3S 服务的启动而结束。

如果启动失败,请使用日志命令查找原因,检查命令、haproxy 配置和迄今为止所做的步骤。

如果需要重新开始,请向上滚动查看输出。

你将看到 killall.sh 脚本和 uninstall.sh 脚本。运行这两个脚本,然后重启。你就会拥有一个干净的节点,这样就可以纠正任何问题并再次尝试。

  1. 如果执行以下命令,就会看到master和worker加入命令:
service k3s status

如果没有,就直接执行如下命令:

Masters:

curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s - server   --token=your_token   --datastore-endpoint="https://haproxy:2379"   --datastore-cafile="/etc/pki/k3s/etcd-ca.crt"   --datastore-certfile="/etc/pki/k3s/server.crt” \

同样,请使用自己的参数进行替换。使用相同的标记。

Workers:

curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE="644" sh -s - agent   --token=your_token   --server https://haproxy:6443   --datastore-endpoint="https://haproxy:2379"   --datastore-cafile="/etc/pki/k3s/etcd-ca.crt"   --datastore-certfile="/etc/pki/k3s/server.crt"   --datastore-keyfile="/etc/pki/k3s/server.key"   --node-name=hostname_of_worker_node

确保相应更改节点主机名。

如果所有加入命令都成功执行,那么恭喜你,现在拥有了一个生产就绪的 Kubernetes 集群!

如果出现故障,请检查命令和配置,必要时使用卸载脚本。

此外,这也是检查 HAProxy 控制面板的好时机。如果集群运行良好,可以看到所有 etcd 节点和主节点都显示为绿色,并且所有节点都有流量。

现在,我们有了一个 Kubernetes 集群,很好!但还没完!


既然我们已经有了一个可用的 Kubernetes 集群,需要分布式存储来存储应用。如前所述,我们将使用 ISCSI 存储和 OCFS2。

你可以使用任何有足够空间的设备,这些设备可以提供 ISCSI 服务,也可以使用你喜欢的方法将共享卷呈现给服务器/虚拟机。

首先,我们需要安装和配置 ISCSI 服务器。

如上所述,我为此使用了一个带有大磁盘的虚拟机。

  1. 准备节点
apt update && apt upgrade
  1. 安装 iSCSI 目标服务:
apt install tgt -y
  1. 检查 iSCSI 目标服务状态:
systemctl status tgt


 tgt.service - (i)SCSI target daemon
     Loaded: loaded (/lib/systemd/system/tgt.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2023-22-08 07:13:04 UTC; 23s ago
       Docs: man:tgtd(8)
   Main PID: 7770 (tgtd)
     Status: "Starting event loop..."
      Tasks: 1
     Memory: 1.1M
     CGroup: /system.slice/tgt.service
             ??7770 /usr/sbin/tgtd -f

Jul 11 07:13:04 kubesp systemd[1]: Starting (i)SCSI target daemon...
Jul 11 07:13:04 kubesp tgtd[7770]: tgtd: iser_ib_init(3431) Failed to initialize RDMA; load kernel modules?
Jul 11 07:13:04 kubesp tgtd[7770]: tgtd: work_timer_start(146) use timer_fd based scheduler
Jul 11 07:13:04 kubesp tgtd[7770]: tgtd: bs_init(387) use signalfd notification
Jul 11 07:13:04 kubesp systemd[1]: Started (i)SCSI target daemon.
  1. 现在我们可以配置 LUN(Logical Unit Number):
nano /etc/tgt/conf.d/iscsi.conf

复制并粘贴以下内容:

<target iqn.2020-07.example.com:lun1>
     backing-store /dev/sdb
     initiator-address 10.1.0.25
    incominguser iscsi-user password
     outgoinguser iscsi-target secretpass
</target>

将 example.com 更改为你希望用的任何名称。(注意--这不是域名,也不指向 DNS,而只是一个标识符)。

将 /dev/sdb 改为你要使用的磁盘位置。

将 iscisi-user 更改为某个用户名。

将密码和secretpass更改为其他密码。

  • 第一行定义 LUN 的名称。
  • 第二行定义 iSCSI 目标服务器上存储设备的位置和名称。
  • 第三行定义 iSCSI 启动程序的 IP 地址。
  • 第四行定义输入的用户名/密码。
  • 第五行定义目标机将提供给启动程序的用户名/密码,以便相互进行 CHAP 身份验证。
  1. 重新启动 tgt 服务。
systemctl restart tgt
  1. 确认一切工作正常:
tgtadm --mode target --op show

太棒了!我们现在有了一个可以正常工作的目标服务器。现在,我们需要将它连接到 Kubernetes 节点并设置 OCFS。

  1. 对于每个 Kubernetes 节点(仅限工作站和主站)。
apt install open-iscsi -y
  1. 现在,我们可以在 ISCISi 目标机上运行发现程序。
iscsiadm -m discovery -t st -p ip_oftarget_server

应该看到这样的内容:

tgtserver01:3260,1 iqn.2020-07.example.com:lun1
  1. 接下来,需要定义 LUN 设备:
nano /etc/iscsi/initiatorname.iscsi

3a. 添加目标名称:

InitiatorName=iqn.2020-07.example.com:lun1

将其更改为在 tgt 设置中定义的内容。

  1. 接下来,定义 iSCSI 目标服务器上配置的 CHAP 配置,以便从 iSCSI 启动程序访问 iSCSI 目标。

节点配置文件存在于"/etc/iscsi/nodes/"目录中,每个 LUN 都有一个目录。

nano /etc/iscsi/nodes/iqn.2020-07.example.com\:lun1/192.168.1.10\,3260\,1/default

同样,请替换为自己的名称。(在 tgt 服务器上配置的名称)。

添加/修改以下内容:

node.session.auth.authmethod = CHAP  
node.session.auth.username = iscsi-user
node.session.auth.password = password          
node.session.auth.username_in = iscsi-target
node.session.auth.password_in = secretpass         
node.startup = automatic

替换为你的 tgt 配置参数。

  1. 重新启动 iscsi 服务。
systemctl restart open-iscsi iscsid
  1. 如果要验证连接:
iscsiadm -m session -o show
  1. 要验证我们是否有来自目标的存储设备:
lsblk

现在,应该在 tgt 服务器上看到一个空白、未格式化的卷。

  1. 在新设备上创建一个新的 ocfs2 文件系统:
sudo apt update
sudo apt install ocfs2-tools
sudo mkfs.ocfs2 -T mail -L "MyOCFS2Volume" /dev/sdb

将 MyOCFS2Volume 替换为不含空格的名称,只需在一个节点上运行此命令。

8a. 确保在每个节点上安装 ocfs2-tools。

8b. 要在启动时自动加载文件系统,请在每个节点上运行:

sudo nano /etc/fstab

添加以下行:

/dev/sdb      /mnt/ocfs2      ocfs2   _netdev,defaults        0  0

保存并关闭文件,不要重启,也不要挂载文件系统。

现在,我们应该在第一个节点上拥有一个格式化的 ocfs2 卷。确保在所有其他需要存储的 Kubernetes 节点上安装 ocfs2-tools,并加载卷。记住,只需要创建一次文件系统。

现在,我们可以设置 OCFS2 集群了。

  1. 在每个节点上运行以下命令,为安装集群做好准备:
modprobe ocfs2

systemctl enable o2cb
systemctl enable ocfs2
systemctl enable iscsid open-iscsi
  1. 在每个节点上运行初始配置。这一点很重要!需要定义群集名称,请勿使用空格。在每个节点上,当配置向导要求输入集群名称时,每次都输入相同的名称。
dpkg-reconfigure ocfs2-tools

重新启动 o2cb 服务:

systemctl restart o2cb
  1. 接下来定义集群配置。请看下面的示例并运行:
nano /etc/ocfs2/cluster.conf

复制并粘贴以下内容。确保将集群名和详细信息替换为自己的集群名和详细信息。

cluster:
        name = cluster_name # Replace with your own on each line that says "cluster".
        heartbeat_mode = local
        node_count = 5 # The total number of nodes in your OCFS2 cluster, starting with "0".

node:
        cluster = cluster_name
        number = 0
        ip_port = 7777
        ip_address = 10.1.0.5
        name = k3sma01

node:
        cluster = cluster_name
        number = 1
        ip_port = 7777
        ip_address = 10.1.0.6
        name = k3sma02

node:
        cluster = cluster_name
        number = 2
        ip_port = 7777
        ip_address = 10.1.0.7
        name = k3sma03

node:
        cluster = cluster_name
        number = 3
        ip_port = 7777
        ip_address = 10.1.0.8
        name = k3swo01

node:
        cluster = cluster_name
        number = 4
        ip_port = 7777
        ip_address = 10.1.0.9
        name = k3swo02

node:
        cluster = cluster_name
        number = 5
        ip_port = 7777
        ip_address = 10.1.0.10
        name = k3swo03

根据节点数量编辑文件。

这一点很重要:

  • 确保名称部分与该节点的主机名完全匹配,而且必须都在 DNS 或主机文件中。
  • 确保所有条目的集群名相同。
  • 将 IP 更改为自己的 IP。
  • 成员 ID 以 0 开头。

编辑文件并分发到 Kubernetes 集群中的每个节点。

3b. 重新启动 o2cb 和 ocfs2 服务:

systemctl restart o2cb ocfs2

3c. 为确保万无一失,请检查 ocfs2-tools 中的集群名称,确保每个集群配置文件和节点入口中使用的名称相同。

sudo dpkg-reconfigure ocfs2-tools
  1. 开始吧!我们准备好挂载新卷并加入群集了!

在每个节点上运行:

mkdir /mnt/kube
mount -t ocfs2 /dev/sdb /mnt/kube

如果出现任何错误(逻辑错误、加入集群错误等),请检查每个节点上的集群配置文件,确保每个条目中的主机名和集群名一致。

现在应该在每个 Kubernetes 节点上都安装了集群存储。

现在我们准备安装和配置 kubectl 和 Longhorn:

  1. 确保已设置 kubectl,默认情况下,可以进入第一个master并运行:
k3s kubectl get nodes

应该会看到 Kubernetes 节点列表,这意味着 Kubectl 正在运行。

我们需要对k3s设置别名:

nano ~/.bashrc

添加以下行:

alias kubectl='k3s kubectl'

保存文件并运行:

source ~/.bashrc

现在可以使用 kubectl 命令,而不是 k3s kubectl。

测试一下:

kubectl get nodes
  1. 现在我们可以部署 Longhorn,用它来管理存储:
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.5.1/deploy/longhorn.yaml

如果你想查看部署:

kubectl get pods \
--namespace longhorn-system \
--watch

这需要几分钟时间,可能是一个漫长的过程,请等待完成后再继续操作。

现在你应该已经安装了 Longhorn。

可以访问 Longhorn 网络界面(请参阅 Longhorn 安装说明中的端口和访问方法)。

  1. 你可以进入 Longhorn 面板的"节点"部分,点击"+"图标查看该节点上的所有存储。如果要添加任何存储,如 OCFS2 卷,请进入右侧菜单,选择每个节点的 "编辑节点和磁盘",然后就可以将卷和其他存储添加到每个节点上。

要使用 Longhorn 存储,只需使用 Longhorn 存储类部署应用程序即可。

接下来是 Kubernetes 控制面板(如果你想使用的话)。

Github 上的指南已经清理过了,所以我将直接指向那里:

  1. 安装:https://github.com/kubernetes/dashboard(部署命令可在发布页面找到)。

  2. 创建用户进入仪表板:https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md


就是这样!现在你就拥有了一个可随时投入生产的高可用 Kubernetes 集群,具有负载均衡功能、外部 etcd 集群,以及基于 OCFS2 集群文件系统的托管存储。


你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!

本文由mdnice多平台发布