跳到主要内容

搭建 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 示例应用

软件成本评估

· 阅读需 9 分钟

1. 概述

本文介绍软件成本评估的一些相关标准和评估方法,内容包括:

  • 软件功能规模度量和成本费用测算相关的现行国家标准。
  • 软件功能规模度量的国际标准,五种度量方法:分别为 IFPUG、MARK Ⅱ、COSMIC、NESMA 和 FiSMA 方法。
  • 当前 IFPUG 方法和 NESMA 方法是目前最主要的标准,优先考虑采用。

2. 国家标准(功能规模度量和成本费用测算)

2023年3月17日,中华人民共和国国家标准公告(2023年第1号)发布,公告中发布了一系列国家标准,其中包含三项软件功能规模测量国家标准,标准由全国信息技术标准化技术委员会归口,全国信息技术标准化技术委员会软件与系统工程分会执行 ,主管部门为国家标准化管理委员会。

三项软件功能规模测量国家标准如下:

标准类型标准编号标准名称发布日期实施日期
荐性国家标准GB/T 42448-2023系统与软件工程 功能规模测量 FiSMA1.1方法2023-03-172023-10-01
推荐性国家标准GB/T 42449-2023系统与软件工程 功能规模测量 IFPUG方法2023-03-172023-10-01
推荐性国家标准GB/T 42452-2023系统与软件工程 功能规模测量 COSMIC方法2023-03-172023-10-01

其它现行的相关国家标准(截止:2024年6月):

标准类型标准编号标准名称发布日期实施日期
推荐性国家标准GB/T 36964-2018软件工程 软件开发成本度量规范2018-12-282019-07-01
地方标准 北京DB11/T 1010-2019信息化项目软件开发费用测算规范2019-06-182019-10-01
地方标准 昆明DB5301/T 102-2024应用软件定制开发成本测算指南2024-01-012024-02-01
地方标准 温州DB3303/T059-2023政务信息化项目软件开发费用测算规范2023-01-162023-02-16
地方标准 贵州DB52/T 1653-2022软件开发费用测算规范2022-03-032022-06-01
地方标准 成都DB5101/T 5-2018信息化项目软件开发费用测算规范2018-07-012018-07-02
行业标准SJ/T 11618-2016软件工程 MK II功能点分析计数实践指南2016-01-152016-06-01
行业标准SJ/T 11617-2016软件工程 COSMIC-FFP 一种功能规模测量方法2016-01-152016-06-01
行业标准SJ/T 11619-2016软件工程 NESMA 功能规模测量方法版本2.1 使用功能点分析的定义和统计准则2016-01-152016-06-01
行业标准SJ/T 11620-2016 信息技术 软件和系统工程 FiSMA1.1功能规模测量方法2016-01-152016-06-01
提示

上述标准有一些可以在官网进行查看,有一些采用了ISO、IEC等国际国外组织的标准,由于涉及版权保护问题,官网不提供在线阅读服务。 如需正式标准出版物,可在中国质量标准出版传媒有限公司(中国标准出版社)主办的中国标网进行购买。

3. 国际标准(功能规模度量)

功能规模度量相关国际标准(截止:2024年6月):

标准编号标准名称发布日期说明
ISO/IEC 20926:2009Software and systems engineering — Software measurement — IFPUG functional size measurement method 20092009-12IFPUG 方法
ISO/IEC 19761:2011Software engineering — COSMIC: a functional size measurement method2011-03COSMIC 方法
ISO/IEC 20968:2002Software engineering — Mk II Function Point Analysis — Counting Practices Manual2002-12Mk II 方法
ISO/IEC 24570:2018Software engineering — NESMA functional size measurement method — Definitions and counting guidelines for the application of function point analysis2018-02NESMA 方法
ISO/IEC 29881:2010Information technology — Systems and software engineering — FiSMA 1.1 functional size measurement method2010-08FiSMA 1.1 方法

4. 五种功能规模度量方法

在度量方法的发展演进中,有五种方法被 ISO 国际标准组织接受成为了 ISO 国际标准,分别是:

  • IFPUG
  • Mark-II
  • NESMA
  • FiSMA
  • COSMIC

1979年10月,Allan Albrecht 博士首次提出了一种评估软件系统功能的技术方法。他的技术方法被采用,成为国际标准。1987 年,IFPUG 成立,负责管理和发展 Albrecht 的技术。在接下来的几年中,又启发了其他几种度量方法出现。它们(按出现顺序)是:Mark-II(1988)、NESMA FPA(1990)、FISMA(199x)和 COSMIC(1998)。

五种度量方法的发展历史

history-of-functional-size-measurement

5. 该选取哪种方法标准

对于上述五种不同的规模度量标准,它们的功能点类型、应用范围、可操作性和应用现状等方面都有各自不同的特点,但就其应用的广泛程度来看,IFPUG 标准和 NESMA 标准仍然是目前最主要的标准。国际组织中超过 90% 的数据采用 IFPUG/NESMA 方法,国内的行业数据则 100% 采用 IFPUG/NESMA 方法;同时,由于 IFPUG 方法和 NESMA 方法被认为是等效的(即 IFPUG 方法所度量的1个功能点基本等同于 NESMA 方法所度量的一个功能点),近几年各行业在应用软件成本度量行业及国家标准时,主要采用 IFPUG/NESMA 方法,各地政府在制订地方标准时,也主要参考 IFPUG/NESMA 方法。

6.相关网站:

[1] 全国标准信息公共服务平台
[2] 国家标准全文公开系统
[3] 中国质量标准出版传媒有限公司(中国标准出版社)
[4] 中国质量标准出版传媒有限公司(中国标准出版社) 主办中国标网
[5] 北京软件造价评估技术创新联盟
[6] 中国软件行业协会软件造价分会
[7] ISO 国际标准化组织
[8] IFPUG 国际功能点用户组
[9] nesma
[10] COSMIC

7.其它参考

[1] 40 Years of Function Points: Past, Present, Future
[2] 五种ISO功能点方法介绍
[3] COSMIC 度量手册中文版
[4] COSMIC-FFP and IFPUG 4.1 Similarities and Similarities and Differences

用 BPMN 进行业务流程建模

· 阅读需 5 分钟

1. 概述

本文介绍在梳理客户业务流程时,使用 BPMN 来进行流程建模绘图。 并提供一些可以供学习的资源链接。

2. 使用 BPMN 表达业务流程的好处

  • 简单易懂一目了然。
  • 具有丰富的符号,可以精确的表示从简单到复杂的每个用例。
  • 为需求人员提供了以图形符号理解和表达客户业务流程的能力,并可以以标准方式向其它相关方传达这些信息。
  • 它是工作流建模的标准。是众多商业或开源工作流引擎底层采用的技术。

3. BPMN 简介

BPMN(Business Process Modeling and Notation 业务流程建模和表示法) ,是业务流程建模的全球标准。BPMN 图表允许项目中不同的相关方可视化的表达业务流程。项目中的业务客户、需求分析师、开发人员、业务经理,每个人都使用相同的表达语言来描述业务流程,从而更容易使业务需求沟通的更加准确和高效。

BPMN 最初由 Business Process Management Initiative (BPMI) 开发,是一种用于记录业务流程的精确图形符号。它通过直观地描述完成特定流程所需的业务活动和信息流的顺序来解决流程规范的歧义。

自 2005 年以来,BPMN一直由对象管理组 Object Management Group(OMG)维护。BPMN 2.0 是 OMG 关于流程改进三个标准之一,另外两个是:CMMN(Case Management Model Notation 案例管理模型符号)和 DMN(Decision Model and Notation 决策模型符号)。

当前 OMG 的 BPMN2.0.1 规范已作为国际标准 ISO/IEC 19510:2013 Information technology — Object Management Group Business Process Model and Notation 发布。

4. 可视化编辑器

参见:安装 Red Hat Process Automation Manager VS Code 扩展捆绑包

5. 入门指南

5.1 BPMN 提供以下三种图类型

  • Collaboration diagrams 协作图显示了使用多个池的两个或多个进程之间的交互。协作图侧重于每个池执行的工作,反过来,每个池可以在彼此之间传递消息。
  • Choreography diagrams 编排图显示了两个或多个参与者之间的交互。编排图可以包含在协作中,添加任务和序列,以确定参与者如何更充分地交互。
  • Conversation diagrams 会话图是协作图的简化版本。它们显示了业务流程中的一组相关消息交换。

5.2 入门指南

这是一篇简单的入门指南,介绍了基本符号的使用。

5.3 一个简单的人员招聘需求发布的示例

personnel-recruitment

6. 接下来

本文的内容非常简略,只是一个简单的介绍,下面的几个链接资源包括了上面所提到的内容,可参考。

7. 其它一些额外的资料

系统与软件工程国家标准(GB)与国家军用标准(GJB)

· 阅读需 8 分钟

1. 系统与软件工程标准简述

系统与软件工程领域国外有一系列指导标准,随着近年来我国信息技术的发展,国家也推出了中国自己的标准,这些标准不是强制性的,而是推荐和建议指导性质的标准。这些标准种类繁多,覆盖了系统与软件工程领域的各个过程,其中有一些标准是比较重要的,这里仅列出国家标准(GB)和国家军用标准(GJB)中最主要的几个。

2. 国家标准(GB)

提示

下述标准是当前现行标准(截止:2024年4月),有一些可以在全国标准信息公共服务平台官网进行查看,有一些采用了ISO、IEC等国际国外组织的标准,由于涉及版权保护问题,官网不提供在线阅读服务。 如需正式标准出版物,可在中国质量标准出版传媒有限公司(中国标准出版社)主办的中国标网进行购买。

GB/T 虽然是国家推荐标准,但如果被纳入经济合同中,就具有法律上的约束性;GB/Z 则不具有法律上的约束性。

(1)基础标准

标准类型标准编号标准名称发布日期实施日期
推荐性国家标准GB/T 11457-2006信息技术 软件工程术语2006-03-142006-07-01
指导性国家标准GB/Z 31102-2014软件工程 软件工程知识体系指南2014-09-032015-02-01

(2)文档化标准

标准类型标准编号标准名称发布日期实施日期
推荐性国家标准GB/T 8567-2006计算机软件文档编制规范2006-03-142006-07-01
推荐性国家标准GB/T 9385-2008计算机软件需求规格说明规范2008-04-112008-09-01

(3)生存周期管理标准

标准类型标准编号标准名称发布日期实施日期
推荐性国家标准GB/T 8566-2022系统与软件工程 软件生存周期过程2022-10-122023-05-01
推荐性国家标准GB/T 22032-2021系统与软件工程 系统生存周期过程2021-04-302021-11-01
推荐性国家标准GB/Z 31103-2014系统工程 GB/T 22032(系统生存周期过程)应用指南2014-09-032015-02-01

(4)质量与测试标准

标准类型标准编号标准名称发布日期实施日期
推荐性国家标准GB/T 25000.1-2021系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第1部分:SQuaRE指南2021-04-302021-11-01
推荐性国家标准GB/T 25000.2-2018系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第2部分:计划与管理2018-12-282019-07-01
推荐性国家标准GB/T 25000.10-2016系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第10部分:系统与软件质量模型2016-10-132017-05-01
推荐性国家标准GB/T 25000.12-2017系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第12部分:数据质量模型2017-11-012018-05-01
推荐性国家标准GB/T 25000.20-2021系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第 20 部分:质量测量框架2021-04-302021-11-01
推荐性国家标准GB/T 25000.21-2019系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第21部分:质量测度元素2019-08-302020-03-01
推荐性国家标准GB/T 25000.22-2019系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第22部分:使用质量测量2019-08-302020-03-01
推荐性国家标准GB/T 25000.23-2019系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第23部分:系统与软件产品质量测量2019-08-302020-03-01
推荐性国家标准GB/T 25000.24-2017系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第24部分:数据质量测量2017-11-012018-05-01
推荐性国家标准GB/T 25000.30-2021系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第30部分:质量需求框架2021-04-302021-11-01
推荐性国家标准GB/T 25000.40-2018系统与软件工程 系统与软件质量要求和评价(SQuaRE)第40部分:评价过程2018-12-282019-07-01
推荐性国家标准GB/T 25000.41-2018系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第41部分:开发方、需方和独立评价方评价指南2018-12-282019-07-01
推荐性国家标准GB/T 25000.45-2018系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第45部分:易恢复性的评价模块2018-12-282019-07-01
推荐性国家标准GB/T 25000.51-2016系统与软件工程 系统与软件质量要求和评价(SQuaRE) 第51部分:就绪可用软件产品(RUSP)的质量要求和测试细则2016-10-132017-05-01
推荐性国家标准GB/T 25000.62-2014软件工程 软件产品质量要求与评价(SQuaRE) 易用性测试报告行业通用格式(CIF)2014-09-032015-02-01

3. 国家军用标准(GJB)

主要标准

  • GJB 5000B-2021 军用软件能力成熟度模型
  • GJB 2786A-2009 军用软件开发通用要求
  • GJB 438C-2021 军用软件文档编制通用要求
  • GJB 5612-2006 军队计算机信息系统安全保密防护要求及检测评估方法
  • GJB 9001C-2017 质量管理体系标准
  • GJB/Z 141-2004 军用软件测试指南
  • GJB 439A-2013 军用软件质量保证通用要求
  • GJB 2115A-2013 军用软件研制项目管理要求
  • GJB 8000-2013 军用软件研制能力等级要求
  • GJB/Z 161-2012 军用软件可靠性评估
  • GJB/Z 102A-2012 军用软件安全性设计指南
  • GJB/Z 172-2015 军用软件风险管理指南
  • GJB 5234-2004 军用软件验证和确认

云原生应用架构设计原则

· 阅读需 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

可视化项目进展一 - Burndown Chart(燃尽图)

· 阅读需 8 分钟

1.用 Burndown Chart(燃尽图)可视化项目进展

燃尽图用于衡量工作进度,它反映的是完成的工作量以及剩余的工作量之间的关系。

下面是一个简单的燃尽图示例,这里为了简单起见,假设总共有 100 个任务项要完成,需要 10 天的时间来完成它们。用纵轴表示 100 个任务项,用横轴表示 10 天。

对于任何一项工作,最理想的方式是每天以一致的速率进行。在这种情况下,意味着每天要计划完成 10 个任务(10天*10个任务等于100个任务总数)。

实际上,如果第一天只完成了五个任务,第二天完成了四个任务,第三天完成了两个任务,则进度落后于计划,因为实际完成数少于了计划数,后续团队需要努力赶上,在接下来的几天里,会完成比原计划更多的任务,在项目结束时,燃尽图可能会如下所示:

信息

下载这个图表的 Excel 文件。Download

burndown-chart-simple.png

2. 更实际一点的示例

信息

下载这个图表的 Excel 文件。Download

burndown-chart-demo

  • 横坐标表示一个时间周期,这里表示一个 sprint 周期(15天)
  • 纵坐标:左坐标轴表示待完成的工作量,右坐标轴表示每日完成的工作量(小时数或故事点数)
  • 三条折线:
    • Ideal Trend(绿色):理想线,假设按照固定速率每天完成 25 (小时或故事点)的趋势线。
    • Remaining Effort(Actual)(蓝色):实际的完成工作进度。
    • Trend Line(Actual)(红色):实际完成工作进度的趋势线。
  • Daily completed:实际每天完成的工作。
  • 在第7天之前,蓝色线在绿色线上方,表示开发进度落后。从第7天蓝色线在绿色线下方,表示进度逐步追赶上来。

3. 燃尽图的类型

有几种类型的燃尽图常用于敏捷项目管理:

  • Sprint 燃尽图:这种类型的燃尽图跟踪一个 Sprint 中剩余的工作。它帮助敏捷团队在短迭代期间监控他们的进度,并确保他们在设定的时间范围内按计划完成 Sprint 目标。
  • 产品 Backlog 燃尽图:与 Sprint 燃尽图不同,产品燃尽图表示整个项目剩余的总体工作。它提供了项目维度进度的视图,并帮助项目经理和团队跨多个 Sprint 或迭代跟踪工作的完成情况。
  • 发布燃尽图:显示了产品发版的所有计划功能和需求的进度。

4. 燃尽图有什么好处?

  • 监控工作进度:允许敏捷团队跟踪项目的所有剩余工作并预测何时完成。
  • 告警:当偏离计划发生时提醒团队,以便及时采取纠正措施。
  • 决策影响:显示项目期间做出的决策的效果,并为未来的决策提供信息。
  • 沟通:促进团队和利益相关者内部的进度沟通,确保每个人都了解情况。
  • 估计:帮助根据当前进度和趋势估计工作何时完成。
  • 动机:通过展示进度和提供绩效反馈来鼓励团队成员表现得更好。
  • 透明度:通过明确比较计划和实际进展来提高透明度。
  • 协作:通过让每个人在项目状态和目标上保持一致来促进有效的协作。

5.燃尽图的局限性是什么?

提示

燃尽图并不能展示所有内容。例如,它只显示已完成的故事点数。燃尽图不显示任何变更。燃尽图可能无法很好地适应范围发生重大变化的项目,因此在这种动态环境中准确跟踪进度具有挑战性。因此,我们通常很难判断燃尽图中的变化是由于已完成的待办事项导致,还是由于故事点数的增加或减少所导致。

另一个是它依赖于良好的估计,主要涉及理想工作线的准确性。实际工作线位于理想工作线的上方还是下方取决于任务的原始时间估计的准确性。如果团队高估时间要求,进度似乎是按计划或提前进行的。但是,如果团队低估了时间需求,他们会觉得进度落后。

燃尽图的其它局限性还包括:

  • 工作质量:燃尽图不能反映已完成工作的质量,因为它们只关注已完成任务的数量。
  • 具体挑战:它们可能不反映项目期间遇到的具体挑战,这些挑战可能会影响整体进度。
  • 复杂性:一些项目可能过于复杂,以至于燃尽图无法有效跟踪进度,尤其是当团队要求严格遵守敏捷方法时。
  • 团队成员的压力:如果进度慢于预期,燃尽图会产生过度的压力,影响团队士气和动力。
  • 学习曲线:对于刚接触敏捷方法的团队来说,学习使用燃尽图在敏捷框架内准确估计工作和管理任务可能需要时间并引入复杂性。

6. 燃尽图和燃起图(Burnup Chart )的区别

主要区别在于它们如何表示项目进度。

信息

下载这个图表的 Excel 文件。Download

burnup-chart

  • 红线表示总的工作量,可以看到第6天的时候,发生了变更,总的工作量由 100 变到了 120。
  • 绿线表示当前完成的工作量,最后项目完成时,两条线应该相交。

7. 敏捷和看板方法相关书籍

信息

百度云盘下载 PDF

链接: https://pan.baidu.com/s/1RLyyEnqqzz2NQuBNLohwnQ 提取码: vwvt

可视化项目进展二 - Cumulative Flow Diagram(累积流图)

· 阅读需 4 分钟

1. 用 Cumulative Flow Diagram(累积流图)可视化项目进展

我们希望团队尽可能高效地工作,但是掌握事情的真正进展可能很有挑战性。累积流图是敏捷、精益、Scrum、看板和 SAFe 方法中使用的管理工具,用于随时间可视化和分析工作项流程。可以直观的了解团队的工作情况,以便可以弄清楚如何改进它。

2. 累积流图示例

下面是一个累积流图的示例

信息

下载这个图表的 Excel 文件。Download

cumulative-flow-diagram-demo

累积流图纵轴(表示任务或工作项)、横轴(表示时间间隔)、不同的彩色线或带(表示各个开发阶段)

提示

累积流图的作用是让团队很容易发现项目中的某些东西工作不正常。理想情况下,图表的所有部分应该平滑地一起(几乎平行)上升。这意味着新任务进入工作流程的速度与任务完成的速度大致相同。如果看到突然的跳跃或下降,这表明工作流程有问题。

3. 累积流图可以反映的指标

有四个主要的指标是我们应该关注的,通过了解和跟踪这些指标,可以识别流程效率低下的地方并进行改进。

  • Lead Time 交货时间,任务从流程开始到完成的时间。它是一个重要的指标,因为它揭示了瓶颈在哪里,并提高了交付的可预测性。假设您在晚上8:00下了晚餐订单,您的订单在晚上8:30送达。在这种情况下,您的交货时间是30分钟。这是从您提出请求的那一刻起到您收到请求的这段时间。
  • Cycle Time 周期时间,是完成一个任务花费的时间。假设厨房在晚上8:10收到了,厨师开始准备你的订单。你在晚上8:30收到食物;在这种情况下,你的周期时间是20分钟。这是处理你的订单所需的实际时间。
  • WIP(Work in progress)进行中的工作(在制品)
  • Throughput 吞吐量,团队在指定时间段内交付了多少工作
提示

关于进一步了解如何理解累积流图,可以参考链接:

  • Cumulative Flow Diagram[3]
  • [PDF]The Ultimate Guide To Reading The Cumulative Flow Diagram[6]

参考

[1] Lead time and Cycle Time and the importance of Flow in Kanban
[2] Kanban Metrics: An Overview of the Most Important Kanban System Metrics to Track
[3] Cumulative Flow Diagram
[4] How to read a cumulative flow diagram
[5] What Is a Cumulative Flow Diagram?
[6] [PDF]The Ultimate Guide To Reading The Cumulative Flow Diagram

与客户谈判

· 阅读需 9 分钟

在项目实施过程中,会在各个时间阶段有各种可能的事项要与客户进行沟通或者谈判,通常可能主要是下面几项:

  • 开发报价
  • 交付里程碑与时间进度
  • 系统的设计、架构、解决方案或技术实现方式
  • 需求范围变更
  • 日常工作的方式

需求范围变更,通常是这些事项中最主要的,也是对项目顺利交付影响最大的因素。

在与客户沟通谈判时,有一些原则、方式或方法可以遵循。

1. 定义明确的界限

在项目启动阶段要与客户对一些基础事项形成一致意见,例如:系统的功能目标、总体的里程碑计划、处理接受变更的流程、验收的标准、输出的交付物等。与客户达成一致,这样就有了一个基础的界限边界。

在与客户进行沟通时我们就有了一个这样的基础。如果客户要求更改,要参考这些文件。根据项目的目标、时间来评估。这不是对客户说不,而是引导客户理解所涉及的影响,双方一起来做权衡。

2. 了解客户需求,提供替代方案

可以通过提出开放式问题、积极倾听和总结客户的想法。仔细审查他们的要求、时间和预算,并澄清任何模棱两可或理解上的偏差。了解客户的需求将有助于使自己的建议与他们的期望保持一致,并向客户展示价值和可信度。

在对范围变更做出任何决定之前,评估它们对项目的影响。考虑这些变更将如何影响进度、资源和最终产品的质量。提议的变更是否与项目目标一致,是否值得额外的时间和精力。如果影响太大,可能需要找到一个折衷方案,在不过度资源投入的情况下满足项目目标。

面对迫在眉睫的最后期限,要确定任务的优先级。必须确定哪些功能或任务对项目的成功至关重要,哪些可以推迟或完全放弃。与客户一起根据任务的紧迫性和重要性对任务进行分类。这将指导我们就范围变更做出明智的决定。

当客户要求更改时,必须传达这将对项目时间进度和成本资源产生的影响。解释一个更改可能对项目的各个方面产生的连锁反应。使用清晰的非技术语言来阐明为什么更改可能需要额外的时间或预算。通过使后果具体化,客户更有可能理解额外资源或时间调整的必要性。

提供一个替代的方案,也许可以在系统上线以后的运行阶段再考虑逐步引入新的功能,也许那时的想法会跟现在不同。或者在产品的下一期开发中对其进行改进。与客户一块寻找可能的解决方案。

也许最终我们可以同意这些额外的变更工作,但要协商延长最后期限或额外付款来支付额外的工作。这期间是有非常多的谈判技巧可以运用(参见下面小节 5. 学习利用一些谈判技巧)。

3. 寻求客户高层利益相关者的支持

客户的高层利益相关者才是对项目具有决定权,要让高层利益相关者充分了解项目当前的情况,了解其真实的想法,并寻求支持。

4. 寻求商务支持

最后,也需要保持一定程度的灵活性。在软件项目管理中,变化通常是不可避免的。虽然管理范围变化很重要,但过于僵化会给客户关系带来不好的影响。

当处于僵局时,需要寻求商务支持,大量事实表明,事情在商务层面沟通时,仿佛进入了另一个维度,很多难题也有了解决办法。

5.学习利用一些谈判技巧

罗杰·道森(Roger Dawson)作为国际首席商业谈判大师,以其丰富的谈判经验和深刻的洞察力,创作了广受欢迎的谈判指导书籍《优势谈判》。这本书不仅在全球销量超过1000万册,而且被广泛应用于各种商业和日常谈判场合。

信息

本书有多个版本,最新的英文版
Secrets of Power Negotiating, 25th Anniversary Edition Roger Dawson 2021-10-01

中文版也有多个出版社的不同版本,百度云盘下载 PDF 中文版

《优势谈判》作者:(美)罗杰·道森,刘祥亚译 重庆出版社 2019-11-01

链接: https://pan.baidu.com/s/1rebh0PxY_HAARZQbV7VeLA 提取码: geq8

书中介绍了一些谈判技巧,以下是部分标题摘录:

开局谈判技巧

  • 开出高于预期的条件:强调在谈判开始时提出高于自己期望的条件,以争取更多的谈判空间。
  • 永远不要接受第一次报价:阐述为何不应立即接受对方的首次报价,并探讨如何有效应对。
  • 学会感到意外:通过表现出对对方条件的惊讶,来影响对方的谈判策略。
  • 避免对抗性谈判:倡导通过合作而非对抗的方式来解决分歧。
  • 不情愿的卖家和买家:利用“不情愿”的策略来增强自己的谈判地位。
  • 钳子策略:通过要求对方做出改变来逐步缩小双方的差距。

中场谈判技巧

  • 应对没有决定权的对手:识别并应对那些没有最终决策权的谈判对手。
  • 服务价值递减:讨论在谈判过程中逐步减少让步的价值。
  • 绝对不要折中:解释为何折中往往不是最佳解决方案,并探讨更有效的策略。
  • 应对僵局:提供解决谈判僵局的方法和技巧。
  • 应对困境:讨论在谈判中遇到困境时的应对策略。

终局谈判策略

  • 白脸—黑脸策略:分析并应对这种常见的谈判技巧。
  • 蚕食策略:在谈判即将结束时提出小要求,以逐步达到自己的目标。
  • 如何减少让步的幅度:探讨在谈判中如何以最小的让步换取最大的利益。
  • 收回条件:在必要时收回之前提出的条件,以重新掌握谈判的主动权。
  • 欣然接受:学会在适当的时候接受对方的条件,以达成双赢的谈判结果。