Skip to content
Go back

K3s 学习(六)在 Kubernetes 集群上安装 cert-manager

| 0 Views Edit page

前言

起因是随着业务扩展,又在日本、新加坡以及英国等国家地区增设了不少边缘节点,一个一个维护消耗的精力太多了,因此需要将这些内容分发服务器也做统一管理了,这样后续扩容也更加方便。
这其中的一个痛点是 SSL 证书,主业务 40 刀每年的泛域名证书已经让我很肉疼了。想着能不能让集群中的 pod 都用 Let’s Encrypt 的免费证书,于是便发现了 cert-manager 这个云原生证书管理开源项目,似乎可以做到。
因此便有了这次尝试:先构建一台 K3s Server + 一台 K3s Agent 的最小化 K3s 集群,之后安装 cert-manager,然后启动一个纯前端的项目验证安装成功。


方案概述

  1. 构建一台 K3s Server + 一台 K3s Agent 的最小化 K3s 集群
  2. 检查集群满足 cert-manager 的安装要求
  3. 安装 Helm 并添加 Helm Chart 仓库
  4. 安装 cert-manager
  5. 测试 cert-manager
    • 建立集群证书颁发者 ClusterIssuer
    • 部署纯前端项目
    • 配置 Service 和 Ingress 暴露应用
    • 访问应用检查 SSL 证书

操作步骤

一、构建最小化集群

参考 K3s 官方文档:快速入门指南

最大 100 台的集群需要 K3s Server 至少拥有 4 核心和 8GB 内存。
这里使用了一台 2H8G(可动态扩容)的云服务器作为 K3s Server,另一台 4H16G 的云服务器作为 Agent,均已重装为 Ubuntu 22.04 系统。

可能需要更新下源并安装必要的依赖:

apt-get update
apt-get install curl

安装并标记为 K3s Server

curl -sfL https://get.k3s.io | sh -s - 
# 查看以下 node-token
cat /var/lib/rancher/k3s/server/node-token

安装并标记为 K3s Agent

curl -sfL https://get.k3s.io | K3S_URL=https://$your_node_ip:6443 K3S_TOKEN=$your_node_token sh -

Server 上检查 Agent 来确定集群构建成功:

kubectl get nodes

Server 和 Agent 都出现了

二、检查集群满足 cert-manager 的安装要求

需要满足以下这些基本要求:

打 ✅ 的项目是 K3s 集群自带或者非常基础的条件,无需关注。
打 ⬜ 的项目需要注意。

  • ✅ 集群必须包含一个 Ingress Controller

    文档描述:“对于 RKE、RKE2 和 K3s,你不需要手动安装 Ingress Controller,因为它是默认安装的。”。
    这里的默认负载方案是 traefikservicelb

  • ✅ 集群需要有 kubectl(Kubernetes 命令行工具)

    K3s 集群同样默认安装,我们之前就是通过 kubectl get nodes 这个命令检查节点的。

  • ⬜ 集群需要有 Helm (Kubernetes 包管理器)
  • ✅ 集群需要能够访问互联网

    如果无法联网请参考:离线环境:Kubernetes 安装,我并没有做过实践。

三、安装 Helm 并添加 Helm Chart 仓库

官方文档:安装 Helm - 使用 Apt (Debian/Ubuntu)

K3s Server 上安装一下:

# 必要的依赖
sudo apt install gnupg2
# 安装 Helm
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

安装完成后确认下:

helm version

Helm v3.0+ 安装成功

仓库这里选用 Stable 版本,官方推荐它适用于生产环境:

helm repo add rancher-stable https://releases.rancher.com/server-charts/stable

之后在使用 Helm 安装的时候,很有可能会出现 “Kubernetes cluster unreachable” 错误,需要在安装前运行下面命令来防止:

echo 'export KUBECONFIG=/etc/rancher/k3s/k3s.yaml' >> ~/.bashrc
source ~/.bashrc

四、安装 cert-manager

这一步请参照比 Rancher 官方更新的文档:Installing the Chart

所有命令依然是都在 K3s Server 上运行。
官方 GitHub 仓库确认下版本编号,之后下载最新的 cert-manager.crds.yaml,我当前是 v1.15.3

cd /root/
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.crds.yaml

添加仓库并更新本地缓存:

helm repo add jetstack https://charts.jetstack.io
helm repo update

安装:

这一步出错的可能性非常高
如果下一步安装失败了,会有非常多的冲突项要清理,之后才能进行重新安装。
我比较建议失败了就记录下解决方法,然后重装系统并在执行安装前完成所有必要项目。

# 建立下命名空间
kubectl create namespace cert-manager
# 安装
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --version v1.15.3

安装成功
检查下各 pod 的情况:

kubectl get pods --namespace cert-manager

pod 状态正常

五、测试 cert-manager

1、建立集群证书颁发者 ClusterIssuer

新建配置文件 letsencrypt.yml

vi letsencrypt.yml

注意将 admin@ceshiku.cn 修改为你的邮箱。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: admin@ceshiku.cn
    privateKeySecretRef:
      name: prod-issuer-account-key
    server: https://acme-v02.api.letsencrypt.org/directory
    solvers:
    - http01:
        ingress:
          class: traefik
      selector: {}

部署并查看:

kubectl apply -f letsencrypt.yml
kubectl describe clusterissuer letsencrypt

2、部署纯前端项目

kubectl create namespace logos

新建配置文件 deployment.yml

vi deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rancher-logo-app
  namespace: logos
spec:
  selector:
    matchLabels:
      name: rancher-logo-backend
  template:
    metadata:
      labels:
        name: rancher-logo-backend
    spec:
      containers:
        - name: backend
          image: ruanbekker/logos:rancher
          ports:
            - containerPort: 80

部署并查看:

kubectl apply -f deployment.yml
kubectl get deployment -n logos

3、配置 Service 和 Ingress 暴露应用

新建配置文件 service.yml

vi service.yml
apiVersion: v1
kind: Service
metadata:
  name: rancher-logo-service
  namespace: logos
spec:
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    name: rancher-logo-backend

部署并查看:

kubectl apply -f service.yml
kubectl get service -n logos

新建配置文件 ingress.yml

vi ingress.yml

注意将 logos.ceshiku.cn 修改为你的域名。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
    annotations:
        cert-manager.io/cluster-issuer: letsencrypt-prod
    name: rancher-logo-ingress
    namespace: logos
spec:
  tls:
    - secretName: rancher-logo-k3s-ruan-dev-tls
      hosts:
        - logos.ceshiku.cn
  rules:
  - host: logos.ceshiku.cn
    http:
      paths:
        - pathType: Prefix
          path: /
          backend:
            service:
              name: rancher-logo-service
              port:
                number: 80

部署并查看:

kubectl apply -f ingress.yml
kubectl get ingress -n logos

外部流量先到 Ingress,然后通过 Service 到 Deployment:
Ingress
Service
Deployment

4、访问应用检查 SSL 证书

证书可信:
证书签发自 Let’s Encrypt


各种意外情况

一、Kubernetes cluster unreachable

常在 Helm 安装 cert-manager 时出现,错误内容:

Error: INSTALLATION FAILED: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused

解决方法:

echo 'export KUBECONFIG=/etc/rancher/k3s/k3s.yaml' >> ~/.bashrc
source ~/.bashrc

之后往往需要删除 cert-manager 命名空间方便重新安装:

kubectl delete namespace cert-manager

二、cert-manager 的安装有误

如果你需要重新安装 cert-manager,那么需要删除命名空间:

kubectl delete namespace cert-manager

大概率它会卡住然后命名空间处于 Terminating 状态,那么请参照 Kubernetes 删除 namespace 时一直处于 Terminating 状态的解决方法这篇文章进行强制删除。
之后再通过 kubectl delete 删除冲突的 ClusterClusterRole 等:

官方清理文档:Helm

kubectl delete crd \
  issuers.cert-manager.io \
  clusterissuers.cert-manager.io \
  certificates.cert-manager.io \
  certificaterequests.cert-manager.io \
  orders.acme.cert-manager.io \
  challenges.acme.cert-manager.io
kubectl delete apiservice v1beta1.webhook.cert-manager.io

最后重新安装,重新安装的时候大概率会有其他冲突项需要手动一点点删除


参考资料:


Edit page