在 CentOS Stream 10 上搭建 Kubernetes 集群并支持开发调试与日志查看
搭建 Kubernetes 集群的每个步骤详细的文档
文档 1: 前期准备
1.1 系统更新与基础工具安装
在所有 6 台 CentOS Stream 10 虚拟机上执行以下操作,确保系统为最新状态并安装必要的工具。
操作步骤:
-
更新系统软件包:
Bashsudo dnf update -y
这会更新所有已安装的软件包到最新版本,确保系统稳定性和安全性。
-
安装常用工具(可选但推荐):
Bashsudo dnf install -y vim net-tools wget curl git
这些工具在后续的配置和调试中会很有用。
1.2 禁用 SELinux
SELinux(Security-Enhanced Linux)的安全机制可能会干扰 Kubernetes 的正常运行,因此需要将其禁用。
操作步骤:
-
临时禁用 SELinux:
Bashsudo setenforce 0
此命令会立即将 SELinux 设置为宽容模式(permissive),但重启后会失效。
-
永久禁用 SELinux:
Bashsudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
这会修改 SELinux 的配置文件,使其在系统重启后也保持宽容模式。您可以选择将其设置为
disabled
以完全禁用,但permissive
模式通常也足够。
1.3 禁用 Firewalld
Firewalld 可能会阻止 Kubernetes 组件之间的网络通信,因此需要停止并禁用它。
操作步骤:
-
停止 Firewalld 服务:
Bashsudo systemctl stop firewalld
-
禁用 Firewalld 开机启动:
Bashsudo systemctl disable firewalld
为了简化集群搭建,禁用防火墙是最直接的方式。在生产环境中,您可能需要更精细地配置防火墙规则来允许必要的端口通信。
1.4 禁用 Swap
Kubernetes 官方要求禁用 Swap 内存,否则 kubelet 将无法启动。
操作步骤:
-
临时禁用 Swap:
Bashsudo swapoff -a
此命令会立即关闭所有 Swap 分区。
-
永久禁用 Swap:
Bashsudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
这会注释掉
/etc/fstab
文件中所有 Swap 分区的挂载配置,确保系统重启后 Swap 不会被再次启用。
1.5 配置内核参数
为了让 Kubernetes 能够正确地进行网络通信和容器管理,需要调整一些内核参数。特别是启用 IP 转发和桥接流量。
操作步骤:
-
加载必要的内核模块:
Bashcat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOFsudo modprobe overlay sudo modprobe br_netfilter
-
overlay
模块支持容器的文件系统层叠功能。* -
br_netfilter
模块用于将桥接流量传递给 iptables 进行处理,这是 Kubernetes 网络插件工作的基础。*
-
-
配置 sysctl 参数:
Bashcat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOFsudo sysctl --system
-
net.bridge.bridge-nf-call-iptables
和net.bridge.bridge-nf-call-ip6tables
确保桥接网络流量能够被 iptables 处理,这是 Kubernetes 网络策略和服务的关键。* -
net.ipv4.ip_forward
启用 IPv4 包转发,允许 Pod 之间以及 Pod 与外部之间的通信。* -
sudo sysctl --system
会立即应用这些 sysctl 配置。*
-
1.6 配置主机名解析
为了让集群中的所有节点能够通过主机名相互通信,需要在 /etc/hosts
文件中添加所有节点的 IP 地址和主机名映射。
操作步骤:
-
编辑 /etc/hosts 文件:
在所有节点上,使用 sudo vim /etc/hosts 或其他编辑器打开 /etc/hosts 文件,并添加如下内容。请根据您的实际 IP 地址和计划的主机名进行修改。
# Master Node 192.168.1.10 k8s-master# Worker Nodes 192.168.1.11 k8s-worker1 192.168.1.12 k8s-worker2 192.168.1.13 k8s-worker3 192.168.1.14 k8s-worker4 192.168.1.15 k8s-worker5
确保替换上述 IP 地址为您虚拟机的实际 IP 地址。
您可以通过 hostnamectl set-hostname <your-desired-hostname> 命令设置每个节点的主机名。例如,在 Master 节点上执行 sudo hostnamectl set-hostname k8s-master。
文档 2: 安装容器运行时 (Containerd)
Kubernetes 使用容器运行时来运行容器。Containerd 是一个行业标准的容器运行时,也是 Kubernetes 推荐的选择。以下步骤需要在所有节点上执行。
2.1 添加 Docker Yum 仓库
Containerd 通常会随 Docker Engine 一起发布,或者可以通过 Docker 官方仓库单独安装。这里我们利用 Docker 的 Yum 仓库来安装 Containerd。
操作步骤:
-
添加 Docker CE 的 Yum 仓库:
Bashsudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
此命令会为您的系统添加 Docker 的官方仓库配置,以便
dnf
工具能够找到并安装 Docker 相关的软件包。
2.2 安装 Containerd
仓库添加完成后,现在可以安装 Containerd。
操作步骤:
-
安装 Containerd.io:
Bashsudo dnf install -y containerd.io
-
containerd.io
是 Docker 公司提供的 Containerd 包名。*
-
2.3 配置 Containerd
Kubernetes 要求 Containerd 使用 systemd 作为其 cgroup 驱动,以确保资源管理和监控的正确性。默认情况下,Containerd 可能不是这样配置的。
操作步骤:
-
创建 Containerd 默认配置文件:
Bashsudo mkdir -p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml
这会生成一个默认的
config.toml
配置文件,并将其放置在/etc/containerd/
目录下。 -
修改 Containerd 配置文件以使用 systemd cgroup 驱动:
Bashsudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
此命令会在
config.toml
文件中查找SystemdCgroup = false
这一行,并将其替换为SystemdCgroup = true
。这是 Kubernetes 正常运行的必要配置。
2.4 启动并启用 Containerd 服务
完成配置后,启动 Containerd 服务并设置其开机自启动。
操作步骤:
-
启动 Containerd 服务:
Bashsudo systemctl start containerd
-
设置 Containerd 开机自启动:
Bashsudo systemctl enable containerd
您可以使用
sudo systemctl status containerd
命令来检查服务状态,确保它正在运行且没有错误。
文档 3: 安装 Kubeadm、Kubelet 和 Kubectl
这些是 Kubernetes 集群的核心工具:
-
kubeadm
: 用于初始化 Kubernetes 集群。 -
kubelet
: 在集群中每个节点上运行的代理,用于管理 Pod 和容器。 -
kubectl
: Kubernetes 命令行工具,用于与集群进行交互。
以下步骤需要在所有节点上执行。
3.1 添加 Kubernetes Yum 仓库
为了安装 Kubernetes 组件,您需要配置 Kubernetes 官方的 Yum 仓库。
操作步骤:
-
创建 Kubernetes 仓库文件:
Bashcat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/RPM-GPG-KEY-kubernetes exclude=kubelet kubeadm kubectl EOF
-
baseurl
: 指向 Kubernetes 官方 RPM 仓库的地址。请注意v1.30
,这代表 Kubernetes 的版本。您可以根据需要选择或调整到最新的稳定版本。 -
gpgkey
: 用于验证软件包的 GPG 密钥,确保下载的软件包是真实的、未被篡改的。 -
exclude=kubelet kubeadm kubectl
: 这一行是非常重要的!它告诉dnf
在更新系统时,不要自动更新这三个 Kubernetes 核心组件。这是为了防止在集群运行期间意外更新导致兼容性问题。我们会在安装时明确指定它们。*
-
3.2 安装 Kubeadm、Kubelet 和 Kubectl
仓库配置完成后,现在可以安装 Kubernetes 的核心组件。
操作步骤:
-
安装 Kubernetes 组件:
Bashsudo dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
-
--disableexcludes=kubernetes
: 这一选项是必需的,因为它临时禁用了我们在kubernetes.repo
文件中设置的exclude
规则,从而允许我们安装kubelet
、kubeadm
和kubectl
。*
-
3.3 设置 Kubelet 开机启动
kubelet
是在每个节点上运行的核心组件,必须设置为开机自启动。
操作步骤:
-
启用 Kubelet 服务:
Bashsudo systemctl enable --now kubelet
-
--now
选项表示在启用服务的同时立即启动它。* -
此时
kubelet
会尝试启动,但可能会因为尚未加入集群而处于waiting
或Error
状态,这是正常的。等到集群初始化并加入节点后,它才能正常工作。*
-
文档 4: 初始化 Master 节点
Master 节点是 Kubernetes 集群的控制平面,负责管理集群的状态、调度 Pod、处理 API 请求等。以下步骤仅在您选定的Master 节点上执行。
4.1 初始化 Kubernetes 集群
使用 kubeadm init
命令来初始化 Master 节点,这将安装控制平面组件(如 kube-apiserver, kube-scheduler, kube-controller-manager, etcd 等)。
操作步骤:
-
执行
Bashkubeadm init
:sudo kubeadm init --apiserver-advertise-address=<Master_Node_IP> --pod-network-cidr=<Pod_CIDR> --ignore-preflight-errors=NumCPU
-
<Master_Node_IP>
: 替换为您的 Master 节点的实际 IP 地址。例如:192.168.1.10
。 -
--pod-network-cidr=<Pod_CIDR>
: 这是您的 Pod 网络(所有 Pod 都在这个网络中通信)的 CIDR 范围。这个范围不能与您的宿主机网络重叠。-
如果您计划使用 Flannel 作为网络插件,默认的 Pod CIDR 通常是
10.244.0.0/16
。 -
如果您计划使用 Calico 作为网络插件,您可以选择
192.168.0.0/16
或其他未冲突的范围。在 Calico 的默认安装中,通常会根据集群环境自动选择,但明确指定可以避免潜在问题。如果您不确定,可以先使用10.244.0.0/16
。
-
-
--ignore-preflight-errors=NumCPU
: 这是一个可选参数,用于忽略 CPU 核数不足的警告。如果您在虚拟机上分配的 CPU 核数较少(例如只有 1 核),kubeadm
可能会发出警告。在测试或开发环境中,通常可以忽略此警告。在生产环境中,建议 Master 节点至少有 2 个 CPU 核。*
执行此命令后,
kubeadm
会进行一系列的预检查,然后下载和部署控制平面组件。这个过程可能需要几分钟。 -
4.2 配置 Kubectl
集群初始化成功后,为了能够以普通用户身份使用 kubectl
命令与集群交互,您需要配置 kubeconfig
文件。
操作步骤:
在 kubeadm init
命令成功执行后,您会看到类似如下的输出:
Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou should now deploy a Pod network to the cluster.
Run "kubectl get pods -A" to see the control plane components.
请按照输出中的提示执行以下命令(以普通用户身份):
Bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
-
mkdir -p $HOME/.kube
: 创建一个名为.kube
的目录,用于存放 Kubernetes 配置文件。 -
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
: 将集群的管理员配置文件复制到您的用户目录下。 -
sudo chown $(id -u):$(id -g) $HOME/.kube/config
: 更改kubeconfig
文件的所有者为当前用户,以便您有权限读取和使用它。*
4.3 验证集群状态
配置 kubectl
后,您可以验证控制平面组件是否正常运行。
操作步骤:
-
检查 Pod 状态:
Bashkubectl get pods -n kube-system
您会看到
kube-apiserver
、kube-controller-manager
、kube-scheduler
和etcd
等 Pod,它们应该都处于Running
状态。 -
检查节点状态:
Bashkubectl get nodes
此时,您应该只能看到 Master 节点,并且它的状态可能是
NotReady
。这是因为我们还没有安装网络插件。在下一步安装网络插件后,Master 节点的状态会变为Ready
。
4.4 记录 Worker 节点加入命令
在 kubeadm init
命令成功执行后,输出的最后会有一条 kubeadm join
命令。这条命令是 Worker 节点加入集群的关键,务必复制并妥善保存。
示例 kubeadm join
命令:
Bash
kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
这个命令包含了 Master 节点的 IP 和端口(6443),以及一个临时令牌(
--token
)和一个 CA 证书哈希值(--discovery-token-ca-cert-hash
)。这些是 Worker 节点与 Master 节点建立信任和加入集群所需的凭证。*
文档 5: 安装网络插件 (Calico)
Kubernetes 集群需要一个网络插件来实现 Pod 之间的通信。这里我们选择 Calico,它提供了强大的网络策略功能。以下步骤仅在Master 节点上执行。
5.1 部署 Calico 网络插件
Calico 提供了一个 YAML 文件,其中包含了部署其所有组件所需的 Kubernetes 资源(DaemonSet, Deployment, ServiceAccount, ClusterRole, ClusterRoleBinding 等)。
操作步骤:
-
部署 Calico YAML 文件:
Bashkubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
此命令会从 Calico 官方网站下载最新的稳定版
calico.yaml
文件,并将其中的所有资源应用到您的 Kubernetes 集群中。
5.2 验证 Calico 部署状态
部署后,您需要等待 Calico 的 Pod 都启动并运行正常。
操作步骤:
-
检查
Bashkube-system
命名空间下的 Pod 状态:kubectl get pods -n kube-system
您会看到以
calico-kube-controllers
和calico-node
开头的 Pod。等待所有这些 Pod 都显示Running
状态。calico-node
是一个 DaemonSet,它会在集群的每个节点上运行一个 Pod。 -
检查节点状态:
Bashkubectl get nodes
在 Calico Pod 都成功运行后,之前显示
NotReady
的 Master 节点状态应该会变为Ready
。这表示网络插件已成功部署并开始工作。
文档 6: 加入 Worker 节点
Worker 节点是运行您的应用程序 Pod 的机器。以下步骤需要在所有作为 Worker 的虚拟机上执行。
6.1 执行 kubeadm join
命令
在 Master 节点初始化成功后,您应该已经复制了 kubeadm join
命令(请参考 文档 4.4)。现在,在每个 Worker 节点上执行该命令。
操作步骤:
-
在每个 Worker 节点上执行之前保存的
Bashkubeadm join
命令:sudo kubeadm join <Master_Node_IP>:6443 --token <token> --discovery-token-ca-cert-hash <hash>
-
重要提示: 确保替换
<Master_Node_IP>
、<token>
和<hash>
为您在 Master 节点上初始化集群时获得的实际值。*
执行此命令后,Worker 节点会与 Master 节点建立连接,并下载和启动
kubelet
所需的组件。 -
6.2 验证 Worker 节点加入状态
在 Worker 节点执行 kubeadm join
命令后,回到 Master 节点,检查所有节点的状态。
操作步骤:
-
在 Master 节点上检查所有节点状态:
Bashkubectl get nodes
您应该能看到 Master 节点和所有新加入的 Worker 节点,并且它们的
STATUS
都显示为Ready
。这表示您的 Kubernetes 集群已成功搭建并准备就绪。如果某个 Worker 节点长时间未显示
BashReady
状态,您可以登录到该 Worker 节点,检查kubelet
服务的日志:sudo systemctl status kubelet sudo journalctl -u kubelet -f
日志中通常会提供有关为什么节点未能加入集群的线索。常见的错误可能是网络问题、Swap 未禁用、SELinux 未禁用等。
文档 7: 部署 Dashboard (可选但推荐)
Kubernetes Dashboard 提供了一个基于 Web 的用户界面,方便您可视化管理和监控 Kubernetes 集群。以下步骤仅在Master 节点上执行。
7.1 部署 Kubernetes Dashboard
Dashboard 是一个独立的应用程序,需要像部署其他 Pod 一样将其部署到集群中。
操作步骤:
-
部署 Dashboard 组件:
Bashkubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
此命令会从 Dashboard 的 GitHub 仓库下载推荐的部署 YAML 文件,并将其应用于集群。这会创建
kubernetes-dashboard
命名空间、Deployment、ServiceAccount、ClusterRole 等资源。 -
验证 Dashboard Pod 状态:
Bashkubectl get pods -n kubernetes-dashboard
等待
kubernetes-dashboard
Pod 处于Running
状态。
7.2 创建服务账户并绑定角色
默认情况下,Dashboard 的权限较低。为了能够查看和管理集群中的所有资源,我们需要创建一个具有 cluster-admin
权限的服务账户。
操作步骤:
-
创建
Bashadmin-user
服务账户:cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata:name: admin-usernamespace: kubernetes-dashboard EOF
这会在
kubernetes-dashboard
命名空间下创建一个名为admin-user
的 ServiceAccount。 -
绑定
Bashadmin-user
服务账户到cluster-admin
角色:cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: admin-user roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-admin subjects: - kind: ServiceAccountname: admin-usernamespace: kubernetes-dashboard EOF
此操作将
admin-user
ServiceAccount 绑定到预定义的cluster-admin
ClusterRole,赋予其集群的完全管理权限。
7.3 获取 Bearer Token
登录 Dashboard 需要一个 Bearer Token。我们将获取 admin-user
服务账户的 Token。
操作步骤:
-
获取
Bashadmin-user
的 Token:kubectl get secret $(kubectl get sa admin-user -n kubernetes-dashboard -o jsonpath="{.secrets[0].name}") -n kubernetes-dashboard -o jsonpath="{.data.token}" | base64 --decode
此命令会从 admin-user ServiceAccount 关联的 Secret 中提取 Token,并进行 Base64 解码。
请复制并保存此 Token。在登录 Dashboard 网页时,您需要将此 Token 粘贴到登录框中。
7.4 访问 Dashboard
为了从外部访问 Dashboard,您可以选择不同的方式。kubectl proxy
是一种方便的临时访问方式。
操作步骤:
-
使用
Bashkubectl proxy
转发 Dashboard 流量:kubectl proxy --address='0.0.0.0' --port=8001 --accept-hosts='^*$'
-
--address='0.0.0.0'
: 允许从任何 IP 地址访问代理,而不仅仅是本地主机。 -
--port=8001
: 设置代理监听的端口。您可以根据需要修改。 -
--accept-hosts='^*$'
: 允许所有主机名进行连接。*
执行此命令后,您的终端会停留在运行状态,表示代理正在运行。
-
-
通过浏览器访问 Dashboard:
在您的浏览器中访问以下地址:
http://<Master_Node_IP>:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
将
<Master_Node_IP>
替换为您的 Master 节点的实际 IP 地址。打开此链接后,您会看到 Dashboard 的登录界面。选择
Token
登录方式,粘贴您之前获取的 Bearer Token,然后点击Sign In
。如果您希望 Dashboard 在集群外部长期可用,或者需要更复杂的访问控制,可以考虑创建 Kubernetes Ingress 资源来暴露 Dashboard 服务。
文档 8: 支持开发人员调试和日志查看
为了让开发人员能够方便地调试应用和查看实时日志、SQL 日志等,我们需要部署一些关键的可观测性工具。以下步骤通常在Master 节点上执行。
8.1 日志聚合系统 (Loki Stack - 推荐)
为了集中管理和查询所有微服务的日志,部署一个日志聚合系统至关重要。这里推荐使用 Loki Stack(Loki + Promtail + Grafana),它比 ELK/EFK 更轻量级,且与 Prometheus/Grafana 生态系统集成更紧密。
操作步骤:
-
添加 Grafana Helm 仓库:
Bashhelm repo add grafana https://grafana.github.io/helm-charts helm repo update
我们使用 Helm 来部署 Loki Stack,所以首先需要添加 Grafana 的 Helm 仓库。
-
安装 Loki Stack:
Bashhelm install loki grafana/loki-stack --namespace logging --create-namespace
此命令会安装 Loki、Promtail(负责从每个节点收集日志)和 Grafana(用于日志查询和可视化)。
-
--namespace logging --create-namespace
: 指定将所有组件部署到logging
命名空间中,如果该命名空间不存在则创建。*
-
-
验证 Loki Stack 部署状态:
Bashkubectl get pods -n logging
确保
loki
、promtail
(每个 Worker 节点一个)和grafana
Pod 都处于Running
状态。 -
访问 Grafana:
Grafana 会被部署为一个 ClusterIP Service。为了方便访问,您可以创建 NodePort 或使用 kubectl port-forward。
使用 Port-Forward (推荐用于临时访问):
Bashkubectl port-forward service/loki-grafana 3000:80 -n logging
这将把本地的 3000 端口转发到 Grafana 服务(通常监听 80 端口)。
然后,您可以通过浏览器访问 http://localhost:3000(如果您在 Master 节点上运行此命令,则为 http://<Master_Node_IP>:3000)。
Grafana 默认登录:
-
用户名:
admin
-
密码:默认密码通常会在安装后显示在 Helm 安装的输出中,或者可以通过以下命令获取:
Bashkubectl get secret loki-grafana -n logging -o jsonpath="{.data.admin-password}" | base64 --decode
登录 Grafana 后,您需要配置 Loki 作为数据源。通常,在 Helm 安装后,Loki 数据源会自动配置。您可以在 Grafana 的 "Explore" 页面选择 Loki 数据源,然后使用 LogQL 查询语言来检索您的微服务日志。
-
8.2 Metrics Server (HPA 依赖)
Metrics Server 提供 CPU 和内存等资源指标,是 Kubernetes AutoScaler(HPA)和 kubectl top
命令的必要组件。
操作步骤:
-
部署 Metrics Server:
Bashkubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
这会部署 Metrics Server 到
kube-system
命名空间。 -
验证 Metrics Server 状态:
Bashkubectl get pods -n kube-system | grep metrics-server
确保
metrics-server
Pod 处于Running
状态。 -
测试 Metrics Server:
稍等片刻(可能需要 1-2 分钟让数据收集稳定),然后尝试:
Bashkubectl top nodes kubectl top pods -A
如果能正常显示节点和 Pod 的 CPU/内存使用情况,则表示 Metrics Server 部署成功。
8.3 Prometheus + Grafana (监控与告警)
为了更全面的监控集群和应用程序性能,Prometheus 和 Grafana 是不可或缺的。它们可以收集和展示各种指标,包括您微服务暴露的自定义指标。
操作步骤:
-
添加 Prometheus Community Helm 仓库:
Bashhelm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update
-
安装 Kube-Prometheus-Stack (包含 Prometheus, Alertmanager, Grafana):
Bashhelm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace
这会部署一个完整的监控解决方案,包括 Prometheus Operator、Prometheus Server、Alertmanager 和 Grafana。
-
--namespace monitoring --create-namespace
: 指定将所有组件部署到monitoring
命名空间中。*
-
-
验证部署状态:
Bashkubectl get pods -n monitoring
确保所有相关的 Pod(
prometheus-kube-prometheus-stack-prometheus
、prometheus-kube-prometheus-stack-grafana
等)都处于Running
状态。 -
访问 Grafana (监控):
Prometheus Stack 中的 Grafana 也是一个 ClusterIP Service。同样可以使用 kubectl port-forward 访问:
Bashkubectl port-forward service/prometheus-kube-prometheus-stack-grafana 3001:80 -n monitoring
然后通过
http://localhost:3001
(或http://<Master_Node_IP>:3001
)访问。Grafana 默认登录:
-
用户名:
admin
-
密码:通常会随 Helm 安装信息输出,或通过以下命令获取:
Bashkubectl get secret prometheus-kube-prometheus-stack-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode
登录后,Prometheus 数据源和各种 Kubernetes 仪表盘通常已自动配置。您可以在 Grafana 中探索集群和应用的各种指标。
关于 SQL 日志: Prometheus 主要抓取指标。如果您的 Spring Cloud Alibaba 应用能将 SQL 执行时间、慢查询次数等信息以 Prometheus 可识别的指标格式暴露出来(例如通过 Micrometer 或自定义 Exporter),Prometheus 就能抓取这些指标并进行监控和告警。具体的 SQL 文本日志则应该由 Loki 或 EFK 等日志系统来处理。
-
8.4 开发人员调试支持工具
-
Kubectl: 开发人员必须熟练使用
kubectl
。-
查看实时日志:
kubectl logs -f <pod-name> -n <your-namespace>
-
进入容器内部调试:
kubectl exec -it <pod-name> -n <your-namespace> -- bash
-
端口转发到本地: kubectl port-forward service/<service-name> <local-port>:<service-port> -n <your-namespace> 或 kubectl port-forward pod/<pod-name> <local-port>:<container-port> -n <your-namespace>
这对于在本地 IDE 调试时连接到集群内部的服务非常有用。
-
-
IDE 集成:
-
许多现代 IDE(例如 IntelliJ IDEA Ultimate 版)提供了 Kubernetes 插件。这些插件允许开发人员直接在 IDE 中浏览集群资源、查看日志、执行命令,甚至进行远程调试。建议您的开发团队利用这些工具。
-
-
Ingress Controller (外部访问):
为了让开发人员或外部用户能够访问您的微服务,您需要一个 Ingress Controller 来暴露服务。Nginx Ingress Controller 是一个常用的选择。
操作步骤:
-
添加 Ingress Nginx Helm 仓库:
Bashhelm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
-
安装 Nginx Ingress Controller:
Bashhelm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace
这将在
ingress-nginx
命名空间中部署 Nginx Ingress Controller。 -
验证 Ingress Controller 状态:
Bashkubectl get pods -n ingress-nginx kubectl get svc -n ingress-nginx
您会看到 Ingress Controller 的 Pod 处于
Running
状态,并且会有一个ingress-nginx-controller
的 Service,其类型可能是LoadBalancer
(如果您在云环境中) 或NodePort
(如果您在裸金属环境)。请记下其外部 IP 或 NodePort。 -
配置 Ingress 规则:
为您的微服务创建 Ingress 资源,将外部流量路由到您的 Service。例如:
YAML# my-app-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: my-spring-app-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: / spec:rules:- host: api.yourdomain.comhttp:paths:- path: /pathType: Prefixbackend:service:name: your-spring-service # 替换为您的 Spring Service 名称port:number: 8080 # 替换为您的 Spring Service 端口
然后应用:kubectl apply -f my-app-ingress.yaml
您还需要将 api.yourdomain.com 解析到 Ingress Controller 的外部 IP 地址(或 NodePort 暴露的节点 IP)。
-
文档 9: 部署您的 Spring Cloud Alibaba 项目
现在您的 Kubernetes 集群已经准备就绪,并且相关的可观测性工具也已部署,是时候将您的 Spring Cloud Alibaba 微服务项目部署到集群中了。
9.1 容器化您的应用
您的 Spring Cloud Alibaba 项目首先需要被打包成 Docker 镜像。
操作步骤:
-
编写 Dockerfile:
在每个微服务的根目录下创建 Dockerfile,例如:
Dockerfile# 使用 OpenJDK 作为基础镜像 FROM openjdk:17-jdk-slim# 设置工作目录 WORKDIR /app# 将编译好的 JAR 包复制到容器中 # 假设您的项目构建后 JAR 包在 target 目录下,并且名称为 app.jar COPY target/your-spring-app.jar app.jar# 暴露应用端口 EXPOSE 8080# 运行 Spring Boot 应用 ENTRYPOINT ["java", "-jar", "app.jar"]
-
将
your-spring-app.jar
替换为您实际的 JAR 包名称。 -
EXPOSE 8080
声明了容器将监听 8080 端口,请根据您的 Spring Boot 应用实际监听的端口修改。*
-
-
构建 Docker 镜像:
在包含 Dockerfile 的目录下执行:
Bashdocker build -t your-registry/your-spring-app:<tag> .
-
your-registry
: 替换为您的 Docker 镜像仓库地址(例如docker.io/your-username
或私有仓库地址)。 -
your-spring-app
: 替换为您的应用镜像名称。 -
<tag>
: 替换为镜像版本标签,例如v1.0.0
或latest
。*
-
-
推送 Docker 镜像到镜像仓库:
Bashdocker push your-registry/your-spring-app:<tag>
确保您的 Kubernetes 集群能够访问这个镜像仓库。如果是私有仓库,您可能需要在 Kubernetes 中配置 ImagePullSecrets。
9.2 创建 Kubernetes Manifests
为每个微服务创建 Deployment、Service、ConfigMap 和 Secret 等 YAML 文件。
操作步骤:
-
创建 ConfigMap (用于应用配置):
存储您的 Spring Cloud Alibaba 应用的配置,例如 Nacos 地址、数据库连接信息、Redis 连接信息等。
YAML# configmap-my-service.yaml apiVersion: v1 kind: ConfigMap metadata:name: my-service-confignamespace: default # 替换为您的命名空间 data:application.yaml: |spring:cloud:nacos:discovery:server-addr: nacos-service.nacos.svc.cluster.local:8848 # Nacos 服务在 K8s 内部的地址config:server-addr: nacos-service.nacos.svc.cluster.local:8848file-extension: yamldatasource:url: jdbc:mysql://mysql-service.default.svc.cluster.local:3306/yourdb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername: root# 密码将通过 Secret 注入redis:host: redis-service.default.svc.cluster.localport: 6379# 密码将通过 Secret 注入# ... 其他 Spring Boot 配置
-
Nacos 地址: 使用 Kubernetes Service 的 DNS 名称来访问 Nacos(假设您也将其部署在 K8s 中)。例如
nacos-service.nacos.svc.cluster.local:8848
。 -
MySQL/Redis 地址: 同理,使用它们的 Kubernetes Service DNS 名称。*
-
-
创建 Secret (用于敏感信息):
存储数据库密码、Redis 密码等敏感信息。
YAML# secret-my-service.yaml apiVersion: v1 kind: Secret metadata:name: my-service-secretnamespace: default # 替换为您的命名空间 type: Opaque data:# Base64 编码的密码# echo -n "your-mysql-password" | base64mysql_password: <Base64 编码的 MySQL 密码># echo -n "your-redis-password" | base64redis_password: <Base64 编码的 Redis 密码>
使用
echo -n "your-password" | base64
来生成 Base64 编码的字符串。 -
创建 Deployment (定义 Pod):
定义如何部署和运行您的微服务 Pod。
YAML# deployment-my-service.yaml apiVersion: apps/v1 kind: Deployment metadata:name: my-service-deploymentnamespace: default # 替换为您的命名空间labels:app: my-service spec:replicas: 3 # 您可以根据需要调整副本数量selector:matchLabels:app: my-servicetemplate:metadata:labels:app: my-servicespec:containers:- name: my-serviceimage: your-registry/your-spring-app:v1.0.0 # 替换为您的镜像地址和标签ports:- containerPort: 8080env:- name: SPRING_CONFIG_LOCATION # 将 ConfigMap 作为文件挂载value: /etc/config/application.yamlvolumeMounts:- name: config-volumemountPath: /etc/configreadOnly: trueenvFrom: # 从 Secret 注入环境变量- secretRef:name: my-service-secretvolumes:- name: config-volumeconfigMap:name: my-service-config# 如果您的私有镜像仓库需要认证,请添加 imagePullSecrets# imagePullSecrets:# - name: your-registry-secret
-
image
: 替换为您构建的 Docker 镜像地址。 -
containerPort
: 您的 Spring Boot 应用监听的端口。 -
env
和volumeMounts
: 通过 ConfigMap 挂载配置文件。Spring Boot 可以加载/etc/config/application.yaml
作为其配置。 -
envFrom
: 将 Secret 中的键值对作为环境变量注入到容器中。Spring Boot 可以通过spring.datasource.password
和spring.redis.password
等环境变量获取这些值。*
-
-
创建 Service (暴露服务):
定义如何访问您的微服务。
YAML# service-my-service.yaml apiVersion: v1 kind: Service metadata:name: my-service-service # 服务名称,其他 Pod 将通过此名称访问namespace: default # 替换为您的命名空间labels:app: my-service spec:selector:app: my-service # 匹配 Deployment 的 labelsports:- protocol: TCPport: 80 # Service 监听的端口targetPort: 8080 # Pod 实际监听的端口type: ClusterIP # ClusterIP 仅允许集群内部访问,如果需要外部访问,使用 NodePort 或 Ingress
-
创建 Ingress (如果需要外部访问):
如果您希望通过域名从外部访问微服务,您需要创建 Ingress 资源(前提是您已经部署了 Ingress Controller)。
YAML# ingress-my-service.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: my-service-ingressnamespace: default # 替换为您的命名空间annotations:nginx.ingress.kubernetes.io/rewrite-target: / spec:rules:- host: my-service.yourdomain.com # 替换为您的域名http:paths:- path: /pathType: Prefixbackend:service:name: my-service-service # 您的 Service 名称port:number: 80 # 您的 Service 端口
9.3 部署到集群
准备好所有 YAML 文件后,您可以将其应用到 Kubernetes 集群。
操作步骤:
-
按顺序应用 YAML 文件:
Bashkubectl apply -f configmap-my-service.yaml kubectl apply -f secret-my-service.yaml kubectl apply -f deployment-my-service.yaml kubectl apply -f service-my-service.yaml kubectl apply -f ingress-my-service.yaml # 如果需要 Ingress
确保先创建 ConfigMap 和 Secret,因为 Deployment 会引用它们。
-
验证部署状态:
Bashkubectl get pods -n default # 查看 Pod 状态 kubectl get svc -n default # 查看 Service 状态 kubectl get deploy -n default # 查看 Deployment 状态 kubectl get ingress -n default # 如果有 Ingress,查看 Ingress 状态
确保您的微服务 Pod 都处于
Running
状态。
9.4 使用 Helm (更高级的部署方式)
对于复杂的微服务项目,使用 Helm 管理部署是一个更推荐的做法。Helm 允许您将所有相关的 Kubernetes 资源打包成一个 Chart,方便版本控制、参数化配置和部署。
操作步骤 (简要概念性说明):
-
创建 Helm Chart 骨架:
Bashhelm create my-spring-app
-
编辑 Chart:
将您的 Deployment、Service、ConfigMap、Secret、Ingress 等 YAML 内容放入 my-spring-app/templates/ 目录中,并使用 Helm 的模板语法 ({{ .Values.xxx }}) 来参数化配置。
编辑 my-spring-app/values.yaml 来定义可配置的参数(例如镜像版本、副本数量、Nacos 地址等)。
-
安装 Chart:
Bashhelm install my-spring-app ./my-spring-app --namespace <your-namespace> --create-namespace
-
升级 Chart:
Bashhelm upgrade my-spring-app ./my-spring-app -n <your-namespace>