跳到主要内容

5 篇博文 含有标签「技术管理」

技术管理相关

查看所有标签

搭建 Kubernetes (v1.32) + Istio (v1.24.2) 开发测试环境

· 阅读需 28 分钟
提示

此文档内容最后更新于 2025-02-12

1. 概述

快速建立一个用于开发测试的 k8s 集群有很多种方法,包括:minikube、kubeadm、Docker desktop、kind、MicroK8s 等,另外也可以使用阿里云或华为云等云计算厂商提供的产品服务。如果仅是用于日常开发测试使用,考虑成本和简单方便还是应考虑自建测试集群环境。

同时还需要考虑:

  • 资源占用小
  • 环境可迁移
  • 团队之间可方便分享
  • 单节点和多节点可方便扩展

综合上述的几项关注点,使用 Kubeadm 进行开发测试环境的搭建是比较好的选择。本文将在操作系统 Windows 10 家庭版上从零开始一步一步进行搭建。

2. 最后搭建完的环境和配置项

分类描述
主机操作系统
  • Windows 10 家庭版
  • 版本号 22H2
新建 NAT 网络
  • 名称:NATNetwork
  • 网络地址范围:10.10.0.0/16
网络适配器
  • 名称:vEnthernet(nat-switch)
  • IP:10.10.0.254
  • 子网掩码:255.255.0.0
(可选)SSH 客户端工具 MobaXterm MobaXterm Home Edition v25.0 (Portable edition)
下载 MobaXterm_Portable_v25.0.zip
(可选)命令行终端工具 Windows TerminalWindows Terminal
下载 Windows Terminal
虚拟机Hyper-V 配置
  • 虚拟机名称:k8s-dev
  • iso:ubuntu-24.04.1-live-server-amd64.iso
  • 虚拟机代数:第二代
  • vCPU:2
  • RAM:使用静态固定内存 4096MB
  • 检查点:不使用自动检查点(默认使用标准检查点)
  • 网络适配器:nat-switch
  • 存储:200GB 动态扩展
  • 安全:启用安全启动,Microsoft UEFI 证书颁发机构
操作系统Ubuntu Server 24.04.1 LTS 最小化安装
下载 ubuntu-24.04.1-live-server-amd64.iso
操作系统安装配置
  • 在安装步骤中,选中了 Install OpenSSH server 以便允许通过 ssh 远程访问。
  • Server Name: k8s-dev loginname: administrator password: P@22w0rd
网络配置
  • IP 10.10.0.100
  • 子网掩码 255.255.0.0
  • 网关 10.10.0.254
  • DNS 223.5.5.5 和 223.6.6.6
其它设置
  • 配置阿里云 Ubuntu 源
  • 安装 vim 和 ping 工具

K8s & istio

名称版本Release date备注
containerd 运行时containerd 2.0.22025-01-14下载 containerd-2.0.2-linux-amd64.tar.gz
containerd.service下载 containerd.service
runc v1.2.42025-01-07下载 runc.amd64
(可选)nerdctl v2.0.32025-01-21下载 nerdctl-2.0.3-linux-amd64.tar.gz
Kubernetesv1.32.02024-12-12
cilium-cliv0.16.242025-01-30下载 cilium-linux-amd64.tar.gz
cilium1.17.02025-02-04
istio1.24.22024-12-19下载 istio-1.24.2-linux-amd64.tar.gz
提示

因为有一些资源在外网,你需要有一个稳定的网络环境,如果在安装过程中遇到困难,比如外网域名无法访问或镜像资源无法拉取的问题,可以与我联系。

3. 主机环境准备

3.1 安装 Hyper-V

这里虚拟机使用 Microsoft Hyper-V,在微软的官方 Hyper-V 安装指南【Install Hyper-V】[2] 中给出的安装需求如下:

  • Windows 10 (Pro or Enterprise), or Windows 11 (Pro or Enterprise)
  • 64-bit Processor with Second Level Address Translation (SLAT).
  • CPU support for VM Monitor Mode Extension (VT-c on Intel CPUs).
  • Minimum of 4 GB memory.
  • Note:The Hyper-V role can't be installed on Windows 10 Home or Windows 11 Home.

如果你的操作系统是专业版或企业版,可以按照微软官方安装指南中的方法进行安装,如果是家庭版,官方给出的说法是不能安装,实际上也是可以装的,并且功能也都是完全可用,但需要特殊的方式。因为我们大多数笔记本安装的操作系统都是家庭版,下面是家庭版安装 Hyper-V 的方法,这个方法同样适用于 Windows 10 和 Windows 11 家庭版。

  1. 打开 Windows 记事本,粘贴下面内容到记事本中,并保存到磁盘目录下,保存的文件名为:hv.bat,如下图片所示。
pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hv.txt
for /f %%i in ('findstr /i . hv.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hv.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL
pause

hv-bat

  1. 右键点击这个 hv.bat 文件,选择以管理员身份运行

hv-bat-run

  1. 等待运行完成重启操作系统后,Hyper-V 将自动安装。可以在应用中找到 Hyper-V 管理器

hyper-v-installed

  1. 如果在上一步的应用中没有找到 Hyper-V 管理器,可以按下面步骤操作,打开控制面板,点击启用或关闭 windows 功能。勾选Hyper-V,并确定。

control-panel

windows-features

3.2 (可选)安装 Windows Terminal 命令行终端工具

可参考官方文档【安装并开始设置 Windows 终端】[5] 。此步骤可选,也可使用 Windows 操作系统自带的 Wiondows PowerShell 工具代替。

下载 Windows Terminal

3.2 创建 NAT 网络

我们要在 Hyper-V 中创建 Ubuntu Server 作为 k8s 集群节点。并且我们希望的网络具有下面的几项特性:

  • 虚拟机之间、虚拟机与宿主机之间可以网络互通。
  • 虚拟机要能访问外网,
  • 在需要时,可以增加多个 k8s 虚拟机节点。为了方便对节点进行管理,虚拟机要配置成静态IP。

Hyper-V 安装完成后会有一个默认虚拟交换机(默认的名称为:Default Switch),这个默认的虚拟交换机将自动使用 NAT 网络地址转换向虚拟机提供计算机网络的访问权限。并且此默认虚拟交换机提供 DHCP 和 DNS功能,虚拟机够通过 DHCP 可获得 IP。

这个默认虚拟交换机对应的网络适配器的 IP 地址是操作系统自动分配的(可能是 172.XXX.XXX.XXX),它有操作系统本地冲突检测机制,是操作系统从一个 IP 地址范围中自动选择一个 IP 来进行分配,并将此地址用作连接到它上的虚拟机的 DHCP、默认网关和 DNS 服务器。

另外,这个默认虚拟交换机 Default Switch 不能删除或管理 DHCP,意味着使用这个虚拟交换机的虚拟机不能配置静态IP地址。

基于上面的信息,我们需要的是可以指定静态IP,因此不能使用这个 Default Switch ,需要创建一个自定义的虚拟交换机,使虚拟机可以访问外部网络,并使用自己分配的 IP 地址,而不是通过 DHCP 获得 IP 地址。

例如用 10.10.0.0/16 作为虚拟机也就是 k8s 集群节点的 IP 地址范围,可以做如下分配:

  • k8s-master-1 10.10.0.1
  • k8s-master-2 10.10.0.2
  • k8s-master-3 10.10.0.3
  • k8s-node-1 10.10.0.4
  • k8s-node-2 10.10.0.5

我们需要先创建一个 NAT 网络,也可以参考官网文档【设置 NAT 网络】[3] 进行操作。

危险

注意:由于 Windows 仅支持一个内部 NAT 子网前缀,所以不能创建多个 NAT ,请确保你只有一个 NAT。

可以查询是否已经创建过 NAT。以管理员身份运行 Windows Terminal 命令行工具。

# 查看当前 NAT 网络
Get-NetNat

# 如果存在,可以选择删除存在的 NAT 网络, -Name 参数指定要移除的 NAT 网络名称
# Remove-NetNat -Name [your nat name]

下面命令创建一个名为 NATNetwork 的 NAT 网络,并将网络地址范围设置为 10.10.0.0/16。


# 创建 NAT 网络,名称为 NATNetwork,网络地址为 10.10.0.0/16
New-NetNat -Name NATNetwork -InternalIPInterfaceAddressPrefix 10.10.0.0/16

3.3 创建 Hyper-V 虚拟交换机

可以通过图形界面或命令行创建虚拟交换机并配置网络适配器,下面是用命令行操作方法。

  • 名称:nat-switch
  • IP:10.10.0.254
  • 子网掩码:255.255.0.0
# 创建虚拟交换机 "nat-switch"
New-VMSwitch -SwitchName "nat-switch" -SwitchType Internal

# 记录 "nat-switch" 的 ifIndex 值
Get-NetAdapter

# 设置 "nat-switch" 的 IP 地址为 10.0.0.254
New-NetIPAddress -InterfaceIndex [上面的ifIndex] –IPAddress 10.10.0.254 -PrefixLength 16

上面第一行命令执行后将在 Hyper-V 中创建一个 nat-switch 虚拟交换机,并在网络连接中生成一个网络适配器 vEthernet (nat-switch) 如下图所示:

nat-switch

上面第二行和第三行命令将配置新生成的网络适配器 vEthernet (nat-switch) IP地址和子网掩码,如下图所示。

nat-switch-ip

3.4 (可选)安装 SSH 客户端工具 MobaXterm

可以使用任意 SSH 工具连接虚拟机,这里使用 MobaXterm Home Edition (Portable edition)

Home 版是一个免费工具,安装方法参见官网 [4]

下载 MobaXterm_Portable_v25.0.zip

4. 创建 Ubuntu 虚拟机

4.1 下载安装文件

下载 ubuntu-24.04.1-live-server-amd64.iso

4.2 创建虚拟机

Hyper-V 配置如下:

  • 虚拟机名称:k8s-dev
  • iso:ubuntu-24.04.1-live-server-amd64.iso
  • 虚拟机代数:第二代
  • vCPU:2
  • RAM:使用静态固定内存 4096MB
  • 检查点:不使用自动检查点(默认使用标准检查点)
  • 网络适配器:nat-switch
  • 存储:200GB 动态扩展
  • 安全:启用安全启动,Microsoft UEFI 证书颁发机构
提示

k8s 安装需要至少 2cpu 和 2G 内存。考虑后面需要安装 istio 的 Kiali 仪表板、以及 Prometheus、Grafana、Jaeger 等组件,因此这里为虚拟机分配了 4G 内存。

可以通过图形界面创建 Hyper-V 虚拟机,也可通过命令行的方式创建。下面以命令行的方式创建虚拟机。

以管理员身份运行 Windows Terminal 命令行工具。复制下面的内容并粘贴到命令行窗口。

这里假设虚拟机创建在 D:\Hyper-V 目录下,ubuntu-24.04.1-live-server-amd64.iso 文件保存在 D:\ 根目录下。


$vmName = 'k8s-dev'
$vmPath = 'D:\Hyper-V'
$vmSwitch = 'nat-switch'
$ubuntuISO = 'D:\ubuntu-24.04.1-live-server-amd64.iso'

New-VM -Name $vmName -Path $vmPath -Generation 2

Set-VM -VMName $vmName -ProcessorCount 2 -MemoryStartupBytes 4096MB -StaticMemory -AutomaticCheckpointsEnabled $false

New-VHD -Path "$($vmPath)\$($vmName)\Virtual Hard Disks\$($vmName).vhdx" -SizeBytes 200GB -Dynamic

Add-VMHardDiskDrive -VMName $vmName -Path "$($vmPath)\$($vmName)\Virtual Hard Disks\$($vmName).vhdx"

Add-VMDvdDrive -VMName $vmName -Path $ubuntuISO

Set-VMFirmware $vmName -FirstBootDevice $(Get-VMDvdDrive -VMName $vmName) -EnableSecureBoot on -SecureBootTemplate MicrosoftUEFICertificateAuthority

Get-VMSwitch $vmSwitch | Connect-VMNetworkAdapter -VMName $vmName

4.2 安装 Ubuntu

Ubuntu 安装设置如下:

  • OS Version:Ubuntu Server 24.04.1 LTS
  • 操作系统安装选项:
    • 安装 Ubuntu Server (minimized),在安装步骤中,选中了 Install OpenSSH server 以便允许通过 ssh 远程访问。
    • Server Name: k8s-dev
    • loginname: administrator
    • password: P@22w0rd
  1. 启动虚拟机开始安装

ubuntu-1

  1. 选择安装程序语言,通常选择「English」

ubuntu-2

  1. 设置键盘布局,默认「English US」即可

ubuntu-3

  1. 选择安装类型,这里选择 Ubuntu Server (minimized)
  • Ubuntu Server:这是默认选项,包含了服务器操作系统所需的基本软件包。
  • Ubuntu Server (minimized):精简版本,只包含最小的运行时操作系统,适合高级用户自定义配置。

ubuntu-4

  1. 配置网络连接,这里先不配置

ubuntu-5

  1. 设置代理

如果服务器需要通过代理来访问 Internet,填写代理服务器信息。否则,直接留空并按 「回车」键继续。 ubuntu-6

  1. 设置 Ubuntu 镜像源,这里不指定镜像,待安装完成后配置

ubuntu-7

  1. 磁盘分区

ubuntu-8-1

总磁盘是200G,这里 ubuntu-lv(LV) 只使用了 98.472G 并没有使用整个 ubuntu-vg(VG)的空间。只要简单的把 LV 的空间进行调整,即可使用全部 VG 的 196.945G 空间了,选中 ubunt-lv ,按回车,在右侧菜单中选择 Edit 回车。

ubuntu-8-2

在出现的 LV 编辑界面中,将 Size 填写到最大值 196.945G,或直接删除 Size 里的值 Save 即可,此时系统会自动使用最大值空间。

ubuntu-8-3 ubuntu-8-4 ubuntu-8-5

  1. 设置 Ubuntu 主机名和用户信息
  • Your name:administrator
  • Your Servers Name:k8s-dev
  • Pick a username:administrator
  • Password:P@22w0rd

ubuntu-9

  1. Ubuntu Pro 这里默认跳过

ubuntu-10-1

ubuntu-10-2

  1. Install OpenSSH server

勾选「Install OpenSSH Server」安装 OpenSSH 服务器,方便以后远程访问。

ubuntu-11

  1. 安装系统并重启

ubuntu-12

4.3 配置虚拟机网络

Ubuntu Server (minimized) 安装类型,默认没有 vi 或 vim 编辑工具,需要使用 cat 编辑网络配置文件。

网络配置文件是 /etc/netplan/00-installer-config.yaml

网络配置如下:

  • IP 10.10.0.100
  • 子网掩码 255.255.0.0
  • 网关 10.10.0.254
  • DNS 223.5.5.5 和 223.6.6.6
提示

其中 223.5.5.5 和 223.6.6.6 是阿里云的公共DNS,参见 https://alidns.com/

在 Hyper-V 中启动虚拟机,键入下面内容。


# 备份原配置文件
sudo cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.bak

sudo cat << EOF | sudo tee /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 10.10.0.100/16
routes:
- to: default
via: 10.10.0.254
nameservers:
addresses: [223.5.5.5,223.6.6.6]
EOF

执行下面命令使配置生效


# 使配置生效
sudo netplan apply

# 查看网卡配置
ip addr show

4.4 配置 Ubuntu 源

在上一步进行网络配置后,可以在主机使用 MobaXterm 客户端工具连接到 Ubuntu 虚拟机

连接信息如下:

  • IP:10.10.0.100
  • 用户名:administrator
  • 密码:P@22w0rd

MobaXterm

可以配置任一个国内镜像源,例如:

提示

Ubuntu 镜像源配置文件 Ubuntu 22.04 是 /etc/apt/sources.list ,在 Ubuntu 24.04 已经被移动到 /etc/apt/sources.list.d/ubuntu.sources

这里选择阿里云 Ubuntu 源

# 备份原镜像列表
sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak


# 替换
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list.d/ubuntu.sources

# Update the package list
sudo apt-get update

4.5 安装 vim 和 ping 工具


sudo apt install vim iputils-ping

5. 安装 Kubernetes 集群

5.1 准备

安装的组件和版本如下表所示,在开始安装前,提前下载所需组件。

名称版本Release date备注
containerd 运行时containerd 2.0.22025-01-14下载 containerd-2.0.2-linux-amd64.tar.gz
containerd.service下载 containerd.service
runc v1.2.42025-01-07下载 runc.amd64
(可选)nerdctl v2.0.32025-01-21下载 nerdctl-2.0.3-linux-amd64.tar.gz
Kubernetesv1.32.02024-12-12
cilium-cliv0.16.242025-01-30下载 cilium-linux-amd64.tar.gz
cilium1.17.02025-02-04
istio1.24.22024-12-19下载 istio-1.24.2-linux-amd64.tar.gz

下载的文件:

k8s-istio-component

将文件上传到虚拟机中,如下图。

upload-component

5.2 安装 Containerd 运行时

# 创建 1-containerd.sh 文件,并粘贴下面内容。
sudo vim 1-containerd.sh

# 执行这个批处理文件。
sudo bash 1-containerd.sh

#! /bin/bash

# file:1-containerd.sh
# 需要在所有节点上执行。

# ----------------------------------------------------------------------------------
# 设置使用的版本常量
# ----------------------------------------------------------------------------------

# Containerd
readonly CONTAINERD_VERSION="2.0.2"
# nerdctl
readonly NERDCTL_VERSION="2.0.3"

# ----------------------------------------------------------------------------------
# 安装配置先决条件
# ----------------------------------------------------------------------------------

#
# 禁用交换分区
#
sudo swapoff -a
# 使禁用交换分区更改在重启后保持不变
sudo sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab

#
# 启用 IPv4 数据包转发
#

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

# ----------------------------------------------------------------------------------
# 安装 containerd
# ----------------------------------------------------------------------------------

# 解压缩
sudo tar Cxzvf /usr/local containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz

#
# 通过 systemd 启动 containerd。
#
sudo mkdir -p /usr/local/lib/systemd/system
sudo mv containerd.service /usr/local/lib/systemd/system/

# 重新加载配置
sudo systemctl daemon-reload
# containerd 服务设置为开机自启,并立即启动
sudo systemctl enable --now containerd

#
# 安装 runc
#
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

#
# 配置 Containerd 的 cgroup 驱动为 systemd
#

# 采用二进制安装 containerd 时,需要创建 /etc/containerd 目录
sudo mkdir -p /etc/containerd

sudo containerd config default | sudo tee /etc/containerd/config.toml

# 设置 SystemdCgroup = true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 配置文件中的 sandbox_image = "registry.k8s.io/pause:版本号",因 GFW 无法访问,需要替换为阿里云镜像。
# 替换 sandbox_image = "registry.k8s.io/pause:版本号" 为 sandbox_image = "registry.aliyuncs.com/google_containers/pause:版本号"
sudo sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/' /etc/containerd/config.toml

#
# 重启 Containerd 服务
#
sudo systemctl restart containerd

5.3 安装 k8s 组件 kubeadm、kubelet 和 kubectl

# 创建 2-k8s.sh 文件,并粘贴下面内容。
sudo vim 2-k8s.sh

# 执行这个批处理文件。
sudo bash 2-k8s.sh


#! /bin/bash

# file:2-k8s.sh
# 需要在所有节点上执行。

# ----------------------------------------------------------------------------------
# 设置使用的 k8s 版本常量
# ----------------------------------------------------------------------------------

# Containerd
readonly K8S_VERSION="v1.32"

# ----------------------------------------------------------------------------------
# 1 - 更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包
# ----------------------------------------------------------------------------------
sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# ----------------------------------------------------------------------------------
# 2 - 下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本
# ----------------------------------------------------------------------------------

# 如果 `/etc/apt/keyrings` 目录不存在,则应在 curl 命令之前创建它。
# 在低于 Debian 12 和 Ubuntu 22.04 的发行版本中,/etc/apt/keyrings 默认不存在。 应在 curl 命令之前创建它。
# sudo mkdir -p -m 755 /etc/apt/keyrings
# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
curl -fsSL "https://pkgs.k8s.io/core:/stable:/${K8S_VERSION}/deb/Release.key" | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# 添加 Kubernetes apt 仓库。 请注意,此仓库仅包含适用于特定版本的软件包; 对于其他 Kubernetes 次要版本,则需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本 (你还应该检查正在阅读的安装文档是否为你计划安装的 Kubernetes 版本的文档)。
# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置。
# echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/${K8S_VERSION}/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

5.4 使用 kubeadm 引导集群

sudo kubeadm init \
--image-repository="registry.aliyuncs.com/google_containers" --v=5

集群创建成功后,执行

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

5.5 安装 Pod 网络组件 Cilium

提示

除了 Cilium 外也有一些其它网络插件可以使用,如 Calico,flannel 等。这里以 Cilium 作为示例。

sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
cilium install --version 1.17.0 --set ipam.operator.clusterPoolIPv4PodCIDRList="172.16.0.0/16"

查看安装状态

cilium status
# Or
cilium status --wait

5.6 部署一个测试应用

提示

当前只有一个节点,需要去掉 master 节点污点,否则无法调度 pod 到节点上。

检查是否可以正确部署。

# 删除污点
kubectl taint nodes k8s-dev node-role.kubernetes.io/control-plane:NoSchedule-

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort

# 测试完删除
kubectl delete deployment nginx

6. 安装 Istio

6.1 安装

我们使用 demo 配置文件。 选择它是为了拥有一组适合测试的默认设置,Demo profile 仅用于开发测试.

提示

Istio 支持 Kubernetes Gateway API, 并计划将其作为未来流量管理的默认 API。

与 Istio Gateway 不同, 创建 Kubernetes Gateway 时, 默认情况下还会部署网关代理服务器。 由于不会使用它们,因此我们禁用通常作为 demo 配置文件的一部分安装的默认 Istio Gateway 服务的部署。


tar -xzf istio-1.24.2-linux-amd64.tar.gz

cd istio-1.24.2

# 将 istioctl 客户端添加到路径(Linux 或 macOS)
export PATH=$PWD/bin:$PATH

# 使用 demo 配置文件安装 Istio,无需任何 Gateway
istioctl install -f samples/bookinfo/demo-profile-no-gateways.yaml -y

# 检查安装了什么
kubectl -n istio-system get deploy

# 给命名空间添加标签,指示 Istio 在部署应用的时候,自动注入 Envoy 边车代理:
kubectl label namespace default istio-injection=enabled

下图所示,表示安装成功

istio-installed

安装 Kubernetes Gateway API CRD

Kubernetes Gateway API CRD 在大多数 Kubernetes 集群上不会默认安装, 因此请确保在使用 Gateway API 之前已安装它们。


# 先安装 git
sudo apt install git

kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.0" | kubectl apply -f -; }

6.2 部署示例 Bookinfo 应用

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# 检查启动情况
kubectl get services
kubectl get pods

通过检查响应中的页面标题来验证应用程序是否在集群内运行

# <title>Simple Bookstore App</title>
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

6.3 对外开放 Bookinfo 应用

Bookinfo 应用程序已部署,但无法从外部访问。为了使其可访问, 需要创建一个 Ingress Gateway,它将路径映射到网格边缘的路由。

# 为 Bookinfo 应用创建 Kubernetes Gateway:
kubectl apply -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml

默认情况下,Istio 会为网关创建一个 LoadBalancer 服务。由于我们将通过隧道访问此网关, 因此不需要负载均衡器。如果想了解如何为外部 IP 地址配置负载均衡器, 请阅读 Ingress Gateway 文档。

# 通过注解网关将服务类型更改为 ClusterIP:
kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default

# 要检查网关的状态,运行:
kubectl get gateway

bookinfo-gateway

访问应用程序 将通过刚刚配置的网关连接到 Bookinfo productpage 服务。 要访问网关,需要使用 kubectl port-forward 命令:

  • port-forward 仅供开发和调试。在生产环境中,考虑使用 Service、Ingress 或其他方法来暴露应用。
  • 虽然 port-forward 可以让你访问内部服务,但它不提供任何安全性保障。确保只在受信任的网络中使用。
  • 当你完成转发操作后,记得关闭 kubectl port-forward 命令以释放端口。

# 默认情况下,port-forward 绑定到 127.0.0.1,但你可以指定其他本地 IP。例如,10.0.0.100 或要绑定到所有 IP(慎用)
kubectl port-forward svc/bookinfo-gateway-istio 8080:80 --address 0.0.0.0

打开浏览器并导航到 http://10.0.0.100:8080/productpage 以查看 Bookinfo 应用程序。

如果刷新页面,应该会看到书评和评分发生变化,因为请求分布在 reviews 服务的不同版本上。

bookinfo-webpage

6.5 查看仪表板

Istio 和几个遥测应用做了集成。 遥测能帮了解服务网格的结构、展示网络的拓扑结构、分析网格的健康状态。

使用下面说明部署 Kiali 仪表板、 以及 Prometheus、 Grafana、 还有 Jaeger。

  1. 安装 Kiali 和其他插件,等待部署完成。

kubectl apply -f samples/addons

# 查看部署状态
kubectl rollout status deployment/kiali -n istio-system

# 访问 Kiali 仪表板
istioctl dashboard kiali --address 10.10.0.100

都部署完成后如下图所示:

istio-addons

打开浏览器,访问 http://10.0.0.100:20001/kiali

kiali

在左侧的导航菜单,选择 Graph ,然后在 Namespace 下拉列表中,选择 default 。 要查看追踪数据,必须向服务发送请求。请求的数量取决于 Istio 的采样率。 采样率在安装 Istio 时设置,默认采样速率为 1%。在第一个跟踪可见之前,需要发送至少 100 个请求。 使用以下命令向 productpage 服务发送 100 个请求:

for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done

Kiali 仪表板展示了网格的概览以及 Bookinfo 示例应用的各个服务之间的关系。 它还提供过滤器来可视化流量的流动

kiali-graph

参考资料

[1] 微软虚拟化文档
[2] Install Hyper-V
[3] 设置 NAT 网络
[4] MobaXterm 官网
[5] 安装并开始设置 Windows 终端
[6] Ubuntu 中国官网
[7] 阿里云 Ubuntu 源
[8] 腾讯云 Ubuntu 源
[9] 华为云 Ubuntu 源
[10] containerd 官网
[11] Getting started with containerd [12] runc github
[12] nerdctl
[13] cilium 官网
[14] Kubernetes 官网
[15] istio 官网
[16] BookInfo 示例应用

云原生应用架构设计原则

· 阅读需 16 分钟

1.前言

12 要素应用程序 (12-Factor App) 是由 Heroku 的开发人员定义的用于构建云原生应用程序的一组原则。

然而,它诞生已超过十年,云技术自最初创建以来一直在发展。为了使应用程序能够真正利用现代云基础设施和工具,并在云中蓬勃发展,Kevin Hoffman 修订了最初的12个要素原则,并增加了三项,该书由 O’Reilly 出版社出版。书名是:Beyond the Twelve-Factor App

下面简要介绍这 15 个设计原则。

信息

云原生计算基金会(CNCF)关于云原生技术的定义:

云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。

这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。

2. 15个架构设计原则

2.1 One codebase, one application 一个应用,一个代码仓库

codebase

一个应用一个代码仓库,这里的应用也指微服务,一个微服务通常是具有一定业务边界的功能服务,当我们的软件系统有大量微服务组件时,每个微服务应该有自己的代码仓库。如果多个微服务有共享模块,那么这个共享模块也应该有独立的代码仓库,并使用依赖管理策略去加载它。

2.2 API first API优先

设计 API 时遵循 API 设计规范 OpenAPI v3规范

信息

当前 OpenAPI 规范 v3.1.0 发布时间 2021 年 2 月 15 日

2.3 Dependency management 依赖管理

dependencies

在 Java 项目中,依赖管理的两个流行的工具是 Maven 和 Gradle。工具有助于简化依赖管理的复杂性,开发人员能够声明他们的依赖关系,然后让工具负责实际确保这些依赖关系得到满足。

2.4 Design, build, release, and run 设计,构建,发布,运行

buildreleaserun

这条准则的目标是要最大化的提升发布速度,同时通过自动测试和自动部署来让我们对发布抱有信心。

2.5 Configuration, credentials, and code 配置,证书,和代码

config

配置指会随着部署环境发生变化的值,包括:

  • 后端服务的 URLs 和其他信息,比如 web service 和 SMTP 服务
  • 连接到数据库的必要信息
  • 调用第三方服务的证书
  • 可能需要放到 XMl 或者 YMAL 配置文件的其他属性

配置并不包括程序本身的内部信息,也就是说,如果某一个值在所有的部署环境都是一样的,它就不是配置。

证书是极其敏感的与代码无关的信息,通常来说,程序员会把证书从程序源代码里面提取出来放到属性文件里面,但是这样做并没有解决问题。 因为配置文件本身仍然是代码仓库的一部分,这意味着证书与程序一起发布,这本身就打破了这条规则。

一个最简单的检验证书和配置是否合理的方式,就是假设现在需要把源代码 push 到 GitHub 上面, 如果外面的人需要访问你的代码,你是否把你依赖的服务的敏感信息给暴露出去了呢?不是你的组织内部的人是否看到了内部后端服务的 URLs,证书或者其他敏感的信息呢?

如果能够在不暴露任何敏感信息的情况下去开源你的代码,那么你可能在隔离你的代码、配置、证书方面做的很好了。

外化配置的方式是可以使用一个配置中心,比如开源的 Spring Cloud Configuration Server,或者其他的配置服务产品。

2.6 Logs 日志

logs

将日志视为事件流,Logs 应该被当作一种事件流,也就是说, logs 是程序内部发出来的时间有序的事件序列。一个真正云原生的应用从来不关心如何路由和存储它的输出流。

应该将日志的聚合,处理和存储视为一项非功能性要求,该要求不是由应用程序满足,而是由云提供商或平台上面的其他工具套件来满足。可以使用ELK技术栈(ElasticSearch,Logstash 和 Kibana),Splunk,Sumologic 等工具或任何其他工具来捕获和分析日志。

2.7 Disposability 易处理

通过快速启动和优雅关机最大限度地提高稳健性。 如果一个应用程序不能快速的重启和停止,那么它就不能快速的扩展,部署,发布和恢复。要在构建应用的时候想到这一点。

如果应用程序正在一个高负载的场景下,就需要快速的启动更多的实例去处理这个负载,但是慢启动会阻碍通过扩展去处理较高的负载。如果应用程序不能快速和优雅的关闭,会失去失败场景下快速恢复的能力,不能快速关闭的能力同样会有耗尽资源的风险。

许多应用程序会在启动过程中有一些耗时较长的动作,例如获取数据缓存起来或者加载一些依赖项。需要单独处理这种动作。例如,可以将缓存外部化为后端服务,以便应用程序可以快速启动和关闭,而无需执行启动前加载动作。

2.8 Backing services 支持服务

backingsvcs

将支持服务视为附加资源,将外部组件(如数据库、电子邮件服务器、消息代理和系统人员可以提供和维护的独立服务)视为附加资源。将资源视为支持服务可以提高软件开发生命周期中的灵活性和效率。

这意味着应用程序没有一行代码会与某个特定的服务耦合到一起,可能会有一个用来发送邮件的后端服务,需要通过 SMTP 连接到邮件服务。但是邮件服务的实现细节不会影响到应用,同时应用也不会依赖于某个固定位置的 SMTP 服务器。

2.9 Environment parity 同等环境

dev-prodparity

尽可能的保持开发,预发布,线上环境相同,这一点很重要,以便可以确保所有潜在的错误/故障都可以在开发和测试中识别出来,而不是在应用程序投入生产时暴漏出来。

TestContainers 工具使我们能够确保测试环境也尽可能接近生产环境。

2.10 Administrative processes 管理进程

后台管理任务当作一次性进程运行。

不鼓励将一次性管理或管理任务放在微服务中。包括迁移数据库和运行一次性脚本来进行清理。这些应该作为一次性进程运行,它们可以作为 kubernetes 任务运行。 这样,服务可以专注于业务逻辑。

管理进程示例包括:

  • 数据迁移
  • 运行定时脚本,比如一个凌晨的批量任务
  • 运行一次性的自定义的程序

2.11 Port binding 端口绑定

portbindings

云原生应用通过端口绑定的方式暴露服务。网络可以通过端口号而不是域名来识别服务或应用程序。其原因是,域名和相关的IP地址可以通过手动操作和自动服务发现机制即时分配。因此,将它们用作参考点是不可靠的。根据端口号将服务或应用程序暴露给网络更可靠,也更容易管理。至少,由于网络私有端口号分配和另一个进程公开使用相同端口号之间的冲突而导致的潜在问题可以通过端口转发来避免。

2.12 Stateless processes 无状态进程

process

云原生应用程序应该是一个单一的无状态进程。所有持久状态都必须在应用程序外部,由后端服务提供。因此,无状态不是说不存在状态,而是说状态不能在应用程序中维护。

例如,一个提供用户管理功能的微服务是无状态的,因此所有用户的列表都在后端服务(例如 MongoDB 数据库)中维护。

2.13. Concurrency 并发

concurrancy

向一个大块的单体应用增加CPU核数,增加内存和其他的资源(虚拟的或者物理的),这种做法被称之为垂直扩展,这种做法不适用于云原生应用。

一个更加理想的扩展方式是水平扩展,相比较于把一个本来就很大的服务进程弄的越来越大,可以创建多个进程,然后在这些进程中分配负载。

大多数云提供商已经完善了这一功能,可以配置规则,根据负载或系统中可用的其他运行时遥测动态扩展应用程序实例的数量。

kubernetes 为我们提供了完善的设施来解决水平扩展的问题。

2.14 Telemetry 遥测

telemetry

遥测的字面定义是使用特殊设备对某物进行特定测量,然后使用无线通讯将这些测量传输到其它地方。遥测点到源头的测量是需要通过远程,远距离,无实物连接的方式来完成的。

这里特指监控和测量我们的云原生应用。当需要监控应用的时候,这里通常会有多种不同类型的数据:

  • 定期健康检查
  • 请求审核
  • 业务级别事件
  • 性能指标和系统日志

在规划监控策略时,要考虑清楚到底需要聚合多少信息、信息传入的速率以及要存储多少信息。如果应用程序从1个实例动态扩展到100个实例,那么也会导致日志流量增加百倍。

开源行业标准 OpenTelemeter 是在应用程序中实现有效分布式跟踪的工具,OpenTelemetry 是各类 API、SDK 和工具形成的集合。可用于插桩、生成、采集和导出遥测数据(链路、指标和日志),帮助你分析软件的性能和行为。

2.15 Authentication and authorization 认证和授权

authentication-and-authorization

在理想情况下,所有云原生应用程序都将使用 RBAC(基于角色的访问控制)保护其所有 API 。对应用程序资源的每个请求都应该知道是谁发出请求,以及该使用者所属的角色。这些角色决定调用客户端是否有足够的权限让应用程序接受请求。

有了 OAuth2、OpenID Connect 等工具,各种SSO服务器和标准,以及各种语言特定的身份验证和授权库,安全性应该从一开始就融入到应用程序的开发中,而不应该是在应用程序在生产环境中运行一段时间之后再加上的一个功能。

3. 参考

[1] 云原生计算基金会(CNCF)
[2] 12 要素应用程序 (12-Factor App)
[3] Kevin Hoffman. Beyond the Twelve-Factor App. O’Reilly
[4] Beyond the Twelve-Factor App 中文版
[5] An illustrated guide to 12 Factor Apps
[6] Creating cloud-native applications: 12-factor applications
[7] Beyond the 12 factors: 15-factor cloud-native Java applications
[8] OpenAPI 英文官网
[9] OpenAPI 中文官网
[10] kubernetes
[11] TestContainers
[12] OpenTelemeter
[13] OAuth 2.0
[14] Master OAuth 2.0 from this guide with modern use cases and real-world examples

数据库的版本控制方案

· 阅读需 11 分钟

1. 简介

作为软件开发工作的一部分对数据库进行建模是在项目的早期,但随着开发的进展,数据库模型会存在修改。在项目后期也可能由于客户提出的变更导致数据库模型的修改。许多看似不起眼的改动都可能给系统带来严重的后果。

我们希望有一种方法可以将数据库模型的修改和部署更新尽可能的平滑,把对系统可能的影响降到最低,并且即使发生问题也可以快速定位和修复,不造成毁灭的影响。

2. 数据库部署问题

软件开发中数据库的更改和部署有下面常见的一些问题。

  • 数据库生产部署可能由团队外部的DBA完成,他们不熟悉我们开发的应用程序,也可能不了解数据库结构
  • 手动部署容易出现人为错误
  • 手动部署通常需要等到发版窗口时间
  • 可能会向其他人提供不正确的脚本,从而导致部署错误的代码
  • 数据库的多个副本存在于不同的开发人员计算机上,因此很难确定要使用和部署的正确版本

3.数据库源代码控制示例

假如我们有一个名为 dept 的表。这是创建它的脚本:

CREATE TABLE dept (
id NUMBER,
name VARCHAR(100)
);

我们会将此文件保存为 “dept.sql” 文件,将其添加到我们的存储库中,提交并将其推送到远程代码存储库。

如果想对数据库进行更改怎么办,例如我们增加一个 status 字段?这引出了一个我们该决定如何管理数据库代码的问题。

有两个方案,是基于状态的版本控制和基于迁移的版本控制。

  • 方案一 基于状态

修改原有的 detp.sql 脚本。每当需要对表进行更改(例如添加状态列)时,它就会得到更新。

CREATE TABLE dept (
id NUMBER,
name VARCHAR(100),
status VARCHAR(20)
);
  • 方案二 基于迁移

创建另一个新的脚本 customer_add_status.sql。一个脚本创建客户表,另一个脚本添加状态列。

ALTER TABLE dept ADD COLUMN status VARCHAR(20);

4. 基于状态 VS 基于迁移

基于状态和基于迁移是数据库版本控制的两种方法。

基于状态:当存储反映数据库当前状态的数据库代码时,称为基于状态的版本控制。可以使用版本控制中的代码来创建数据库,脚本表示当前数据库定义是什么。

基于迁移:当存储反映为到达数据库当前状态而采取的步骤的数据库代码时,称为基于迁移的版本控制。版本控制中的脚本反映用于创建对象的原始脚本,以及后续所有变化的过程脚本。

基于状态的好处是

  • 被认为更简单,因为只有一组脚本(例如,每个对象一个脚本,或一些其他划分)。
  • 对象的定义在一个地方,所以任何人都可以打开它看看它应该是什么样子。
  • 版本控制提交历史将告诉我们更改了什么、何时以及谁更改了它们。

基于迁移的好处是

  • 数据库可以建立到某一时间点的状态,这有助于在有多个环境和分支的团队中使用
  • 所有更改都在单独的脚本中,因此知道什么正在更改以及何时更改
  • 由于脚本更小,部署可能更容易

数据库代码应该反映数据库的当前状态,还是应该反映为达到数据库的当前状态而采取的步骤呢?采用哪种方法需要与团队一起来讨论利弊。

通常的建议是使用基于迁移的部署,好处可能更多一些。这带来的另一个问题是可能会有大量过程脚本,当有大量过程脚本或者部署执行脚本带来大量的时间消耗的时候,我们可以用重新确定数据库脚本基线的方式来处理。

5. 重新确定数据库脚本的基线

重新基线化数据库部署脚本涉及将所有数据库部署脚本组合成一组反映数据库当前状态的脚本。这可以减少对同一对象上的数据库所做的更改数量,从而减少部署时间。

例如,假设在一年的时间里,对表进行了几次更改:

  1. 从原始脚本创建表
  2. 添加新列
  3. 添加索引
  4. 更改列的数据类型
  5. 再加三列
  6. 删除列
  7. 将表拆分为两个表

在所有这些脚本之后,很难判断表的样子。可以重新设置脚本基线,而不是为每个部署运行所有这些脚本。这意味着您可以创建一个脚本来创建当前状态的数据库,而不是运行所有这些迁移。

6. Liquibase & Flyway

使用比较广泛的数据库迁移工具有 Liquibase 和 Flyway,这两种工具都可以实现基于迁移的数据库部署工作。有开源的免费版本和付费商业版本。

7. 一些建议原则

下面是一些建议的指导原则。

  • 脚本一旦进入代码库,就不能更改。

一个脚本被添加到版本控制后,如果想对数据库进行更改,无论多小,都要编写一个新脚本。不要更改旧脚本。

  • 使用脚本而不是手动更改数据库。

所有更改都应使用相同的过程完成:编写新的脚本文件并在部署过程中获取它。这有助于避免数据库中的意外错误更改并确保一致性。

  • 确保每个开发人员都有自己的本地数据库,而不是共享的开发数据库。

请确保团队每个人都有自己的本地开发数据库。

  • 避免脚本中的独占锁。

编写的脚本可能会自动或手动在它们正在处理的表上放置独占锁。尽量避免在部署脚本中这样做,因为这会减慢部署过程。不过,这取决于使用的是哪个数据库供应商,因为某些数据库在某些情况下具有表级锁,而另一些则没有。

8. 如何实现上述方案

在团队中实现这一点可能需要一定的时间。技术方面可能需要设置工具和流程。个人方面也可能需要说服人们遵守一些列约定,并在过程中建立信任。

这是从手动数据库部署过程到自动化过程可以采取的步骤的列表。

  • 考虑从一个小的项目和团队开始。
  • 为数据库生成基线模式。这可以手动完成(编写 SQL 脚本)或使用IDE生成。
  • 将数据库脚本添加到源代码管理。
  • 确定用于数据库更改和迁移的工具。
  • 实现所选工具来处理版本控制的脚本。
  • 为每个开发人员实现一个本地数据库
  • 更新部署过程(或创建一个)以从源代码控制中的脚本生成数据库
  • 更新部署过程以将脚本部署到下一个环境(例如 QA )
  • 实施自动化数据库测试。这可能是一大步。
  • 更新部署过程以部署到您的下一个环境(例如 Pre Prod)
  • 更新部署过程以允许用户在需要时(以及测试通过时)触发部署到生产环境
  • 更新部署过程以自动部署到生产环境。

Tekton - 云原生持续集成与交付(CI/CD)工具

· 阅读需 6 分钟

1. 前言

在持续集成与持续交付(CI/CD)领域 Jenkins 是事实上的标准,随着云原生领域技术的发展,微服务架构下的持续集成与持续交付面临新的挑战。Jenkins 开源社区也开启了一个全新的项目 Jenkins X 来应对挑战。它基于 Jenkins 和 Kubernetes 实现,为微服务体系架构下的云原生应用的开发、运行和部署提供了全面的支持。相比于 Jenkins,Jenkins X 复用了 Jenkins 的能力,但更加专注于云原生应用的构建、测试和部署。

Tekton 是一个开源的、供应商中立的框架,用于创建持续集成和交付(CI/CD)系统,由持续交付基金会(CDF) 管理。作为 kubernetes 原生框架,Tekton 是通过为管道、工作流和其他构建块提供行业规范来实现持续交付的现代化。Tekton 允许通过抽象底层实现细节可跨多个云提供商或本地系统构建、测试和部署。

Tekton 和 Jenkins X 都是流行的持续集成/持续交付(CI/CD)工具,Jenkins X 更适用于那些已经熟悉 Jenkins 并希望将其扩展到云原生领域的团队。选择哪个工具取决于具体的项目需求、团队偏好以及团队对云原生技术的支持程度。

2. Tekton 的工作方式

Tekton 的目标是在云原生环境中创建可重用、可组合和声明性的小型构建块。它使用步骤(Step)、任务(Task)、管道(Pipeline)和资源(Resource)来执行此操作,如下图所示。

Tekton-PipelinesArchitecture

图片来源于:developers.redhat.com

  • Step 是对输入执行的操作。如果正在构建 Java 应用程序,它可能会运行一些单元测试或验证代码是否遵循现有的编码标准。Tekton 将在提供的容器中执行每个步骤。对于该Java 应用程序,可以运行安装了 JDK 的基础映像。Step 是 Tekton 中最基本的单元。

  • Task 是按顺序执行的步骤列表。Tekton 在 Kubernetes 的 pod 中运行 Task,这允许在设计一系列相关 step 时拥有一个共享环境。例如,可以在任务中挂载一个卷,该卷将在该特定任务的每个步骤中共享。

  • Pipeline 是可以并行或顺序执行的任务的集合。Tekton 为开发人员提供了如何以及何时执行这些任务的很大灵活性。甚至可以指定任务必须满足的条件才能启动下一个任务。

  • Resource 大多数 Pipeline 需要执行任务的输入,也可以产生输出。在 Tekton 中,这些被称为资源。资源可以是许多不同的类型,如 Git存储库、容器映像或 Kubernetes 集群。

3. Tekton 安装

先决条件

提示

官方 yaml 安装文件中的 image 指向 gcr.io,国内无法访问,需要科学上网。可以使用阿里云提供的镜像文件替代。只是版本略低于官方版本。 参见:阿里云容器计算服务帮助文档-Tekton最佳实践

提示

此安装方式适合作为 Tekton 管道的快速启动安装指南,不适用于生产用途。生产环境官方建议使用Tekton Operator 来安装、升级和管理 Tekton 项目。

kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml

# Specific release
# kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/<version_number>/release.yaml

# 当所有组件在 READY 列下显示1/1时,安装完成。如下图。按 Ctrl+C 停止监控
kubectl get pods --namespace tekton-pipelines --watch

tekton-installed

安装 Tekton Command Line 工具

提示

测试环境为 Ubuntu 24.04 LTS

curl -LO https://github.com/tektoncd/cli/releases/download/v0.38.1/tektoncd-cli-0.38.1_Linux-64bit.deb
sudo dpkg -i ./tektoncd-cli-0.38.1_Linux-64bit.deb

4. 创建一个测试 Task

sudo cat > hello-world.yaml << EOF
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello
spec:
steps:
- name: echo
image: alpine
script: |
#!/bin/sh
echo "Hello World"
EOF

kubectl apply -f hello-world.yaml
sudo cat > hello-world-run.yaml << EOF
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: hello-task-run
spec:
taskRef:
name: hello
EOF

kubectl apply -f hello-world-run.yaml

# Verify that everything worked correctly:
# The value True under SUCCEEDED confirms that TaskRun completed with no errors.
kubectl get taskrun hello-task-run

# Take a look at the logs:
kubectl logs --selector=tekton.dev/taskRun=hello-task-run

5.接下来

7.参考

[1] Tekton 官网
[2] 持续交付基金会(CDF)
[3] 阿里云容器计算服务帮助文档-Tekton最佳实践
[4] Tekton Operator
[5] Visual Studio (VS) Code Tekton Pipelines extension by Red Hat

在 Kubernetes 集群中使用 MetalLB 作为负载均衡器

· 阅读需 3 分钟

在 Kubernetes 中不提供负载均衡的实现,网络负载均衡器的实现依赖于云厂商(阿里云、腾讯云、华为云、AWS、Azue 等),如果是自建集群,而不是选择这些公有云厂商提供的 Kubernetes ,在创建 Service 时,我们只能使用类型是 NodePort 和 ExternalIPs 的服务用做外部访问。

我们希望自建集群也能简单便捷的方式对集群外部暴露服务,MetalLB 这个项目正是为了解决这个问题。

先决条件

安装前有几个先决条件需要查看,特别是网络插件(CNI)的兼容性支持。

官网的安装文档 MetalLB Installation

安装

修改 kube-proxy 参数

kubectl edit configmap -n kube-system kube-proxy
提示

--proxy-mode ProxyMode 使用哪种代理模式:在 Linux 上可以是 'iptables'(默认)或 'ipvs'。 在 Windows 上唯一支持的值是 'kernelspace'。 如果配置文件由 --config 指定,则忽略此参数。

ipvs 参数含义可以参考:

  • IPVS vs. IPTables for kube-proxy in Kubernetes[3]
  • Comparing kube-proxy modes: iptables or IPVS?[4]
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true

安装MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml

查看命名空间下的组件都正常运行

kubectl get all -n metallb-system

alt text

定义要分配给负载均衡器服务的IP地址并配置 2 层通告。

sudo cat > metallb-config.yaml << EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 10.10.0.150-10.10.0.200
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
EOF

kubectl apply -f metallb-config.yaml

测试

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --type=LoadBalancer --port=80

# 可以看到这里分配的地址是 10.10.0.150
kubectl get svc

curl http://10.10.0.150

alt text

参考

[1] 创建外部负载均衡器
[2] 组件工具 kube-proxy
[3] IPVS vs. IPTables for kube-proxy in Kubernetes
[4] Comparing kube-proxy modes: iptables or IPVS?