Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多集群运维(番外篇):SSL证书的管理

多集群运维(番外篇):SSL证书的管理

原创
作者头像
行者深蓝
修改于 2024-01-07 05:44:21
修改于 2024-01-07 05:44:21
7170
举报

概述

在多 Kubernetes 集群环境中,采用泛域名证书管理是一种有效策略。通过申请一个泛域名证书,你能够为同一根域名下的多个子域名提供安全的通信。使用泛域名证书(Wildcard Certificate)和 HashiCorp Vault 对于在多个 Kubernetes 集群中有效地管理证书是一个有效的策略。

下面是一个简单的流程概述:

  1. 申请泛域名证书: 你只需为同一根域名申请一个泛域名证书,该证书可以用于覆盖多个子域名。这可以减少证书的数量和管理成本。
  2. 保存证书到 Vault KV 引擎: 将证书保存到 HashiCorp Vault 中的 Key-Value 引擎。Vault 可以用作安全的中央存储,确保证书的安全性。
  3. 将证书分发到各个 Kubernetes 集群的 master 节点的 /etc/ssl/ 目录。
  4. 在每个集群中使用/etc/ssl/ 目录的证书文件生成 Kubernetes Secret

Demo示例

项目

服务提供商

用途/环境

备注

云服务账号

AWS

通用

云主机

域名

xx云

安全环境

onwalk.net

云DNS服务

阿里云

域名解析

使用xx云的SaaS服务

配置仓库

  1. IAC_code: https://github.com/svc-design/iac_modules.git
  2. Playbook:https://github.com/svc-design/playbook.git
  3. PipeLine : https://github.com/open-source-solution-design/Modern-Container-Application-Reference-Architecture.git

部署vault server

以K3S部署环境,使用 onwalk.net 为例,提前申请好的SSL证书放入部署vault server 环境的节点:

  • /etc/ssl/onwalk.net.key
  • /etc/ssl/onwalk.net.pem

执行shell命令,使用 helm 完成 vault server 的部署

代码语言:yaml
AI代码解释
复制
cat > vaules.yaml << EOF
server:
  ingress:
    enabled: true
    ingressClassName: "nginx"
    hosts:
      - host: vault.onwalk.net
        paths:
          - /
    tls:
      - secretName: vault-tls
        hosts:
          - vault.onwalk.net
EOF
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo up
kubectl create ns vault || echo true
kubectl create secret tls vault-tls  --key=/etc/ssl/onwalk.net.key --cert=/etc/ssl/onwalk.net.pem -n vault
helm upgrade --install vault-server hashicorp/vault -n vault --create-namespace -f vaules.yaml

初始化 vault server

1.Vault部署完成后,需要对Vault服务进行初始化, 执行命令

代码语言:yaml
AI代码解释
复制
kubectl exec -t -i vault-server-0 -n vault -- sh -c "vault operator init -key-shares=5 -key-threshold=3"

2.记录下返回的密钥, 需要严格私密保存,建议多人分开保存(下面示例key已经作废)

代码语言:yaml
AI代码解释
复制
Unseal Key 1: jHeA/olf6URrxshlYqceyuRy8NMx8ICVWaolxfSnRvi+
Unseal Key 2: iAozcZmwczQpkoRwWUm7UO2yi2Ou0dtmsWREyXGaqiIH
Unseal Key 3: 28XG9Gmk/GN3rBJtNhK97dmlLY9jWO9VINAFY+d4lJZe
Unseal Key 4: U4/sW5k+FkIrgnHdBxZUnlg+SU7VRArKkb2Yfjx3qBjz
Unseal Key 5: LN3bp6kkwkeoYCoE7DZ7Y7QQCZPQ7N6NjsIo2PquwgUD

Initial Root Token: s.KJmwUJcHJMF6cUNwhJQpAaAY

当vault服务启动时,它开始是密封(sealed)的状态,需要使用Unseal Key 1-5中的任意3个进行解封(Unsealing )操作,解封后才能vault进行交互。例如认证、管理挂载表,读取等,

3.解封操作,执行命令: kubectl exec -t -i vault-server-0 -n vault -- sh

  • 第一次解封:vault operator unseal jHeA/olf6URrxshlYqceyuRy8NMx8ICVWaolxfSnRvi+
  • 第二次解封:vault operator unseal iAozcZmwczQpkoRwWUm7UO2yi2Ou0dtmsWREyXGaqiIH
  • 第三次解封:vault operator unseal U4/sW5k+FkIrgnHdBxZUnlg+SU7VRArKkb2Yfjx3qBjz
  • 此时检查vault 服务运行状态,执行命令: kubectl get pods -n vault
代码语言:shell
AI代码解释
复制
NAME                                           READY   STATUS    RESTARTS   AGE
vault-server-agent-injector-59bd55cb5f-kdcr4   1/1     Running   0          25m
vault-server-0                                 1/1     Running   0          17m
  1. 登陆Vault UI,确认服务可用

使用 CI pipeline 管理证书

创建一个 GitHub Actions pipeline

使用 ACME 协议从 Let's Encrypt 申请证书,并将结果保存在 Vault Server 中,然后应用集群配置 CertManager 以从 Vault 读取证书,你可以按照以下步骤构建你的 workflow:

  1. 创建 GitHub Repository Secret
    • 在你的 GitHub 仓库中,添加必要的 Secrets,比如 VAULT_TOKENVAULT_URL,以安全地与 Vault 交互。
  2. 设置 GitHub Actions Workflow
    • 在你的 GitHub 仓库中创建一个 .github/workflows 目录。
    • 创建一个新的 YAML 文件,比如 cert-renewal.yml
  3. 编写 Workflow
    • 使用适当的 runner(例如 ubuntu-latest)。
    • 确保你有 ACME 客户端,比如 Certbot,安装在 runner 上。
    • 编写步骤以使用 ACME 协议申请证书。
    • 申请 Let's Encrypt 证书并保存到 Vault

示例 cert-renewal.yml

open-source-solution-design/Modern-Container-Application-Reference-Architecture/.github/workflows/cert-renewal.yml

代码语言:yaml
AI代码解释
复制
name: Renew SSL Certs

on:
  pull_request:
  push:
    paths:
      - '.github/workflows/app-pipeline-renew-ssl-cert.yml'
  workflow_dispatch:
    branches:
      - main
  schedule:
    - cron: '0 0 1 */2 *'  # 每两个月的第一天执行

jobs:
  renew-ssl-certs:
    uses: open-source-solution-design/Modern-Container-Application-Reference-Architecture/.github/workflows/use-renew-ssl-certs.yml@main
    with:
      domain: 'onwalk.net'
    secrets:
      DNS_AK: ${{ secrets.DNS_AK }}
      DNS_SK: ${{ secrets.DNS_SK }}
      VAULT_URL: ${{ secrets.VAULT_URL }}
      VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}

open-source-solution-design/Modern-Container-Application-Reference-Architecture/.github/workflows/use-renew-ssl-certs.yml

代码语言:yaml
AI代码解释
复制
name: Workflow Call Renew SSL Certs
on:
  workflow_call:
    inputs:
      domain:
        required: true
        type: string
    secrets:
      DNS_AK:
        required: true
      DNS_SK:
        required: true
      VAULT_URL:
        required: true
      VAULT_TOKEN:
        required: true

jobs:
  renew-ssl-certs:
    runs-on: ubuntu-latest
    env:
      DOMAIN: ${{ inputs.domain }}
      DNS_AK: ${{ secrets.DNS_AK }}
      DNS_SK: ${{ secrets.DNS_SK }}
      VAULT_URL: ${{ secrets.VAULT_URL }}
      VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          submodules: 'recursive'

      - name: Pre Setup
        run: |
          curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
          sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
          sudo apt-get update && sudo apt-get install vault -y

      - name: Renew SSL Cert
        run: |
          set -x

          # 检查参数是否为空
          check_not_empty() {
            if [[ -z $1 ]]; then
              echo "Error: $2 is empty. Please provide a value."
              exit 1
            fi
          }
          # 检查参数是否为空
          check_not_empty "$DNS_AK" "DNS_AK" && export Ali_Key=$DNS_AK
          check_not_empty "$DNS_SK" "DNS_SK" && export Ali_Secret=$DNS_SK
          check_not_empty "$VAULT_URL" "VAULT_URL"

          rm -fv ${DOMAIN}.key ${DOMAIN}.pem -f
          rm -fv /etc/ssl/${DOMAIN}.* -f
          # Try to issue a certificate from ZeroSSL. If it fails, try Let's Encrypt.
          curl https://get.acme.sh | sh -s email=156405189@qq.com
          sh ~/.acme.sh/acme.sh --set-default-ca --server zerossl --issue --force --dns dns_ali -d ${DOMAIN} -d "*.${DOMAIN}"
          if [ $? -eq 0 ]; then
              echo "Certificate from letsencrypt successfully issued"
          else
            sh ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt --issue --force --dns dns_ali -d ${DOMAIN} -d "*.${DOMAIN}"
            if [ $? -eq 0 ]; then
                echo "Certificate from zerossl successfully issued"
            else
                echo "Command failed"
                exit 1
            fi
          fi
          cat ~/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.cer > ${DOMAIN}.pem
          cat ~/.acme.sh/${DOMAIN}_ecc/ca.cer >> ${DOMAIN}.pem
          cat ~/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.key > ${DOMAIN}.key
          sudo cp ${DOMAIN}.pem /etc/ssl/ -f && sudo cp ${DOMAIN}.key /etc/ssl/ -f

      - name: Write certificate into Vault Server
        run: |
          export VAULT_ADDR=${VAULT_URL}
          export CERT_PATH="certs/${DOMAIN}"

          # Write Certificate and Private Key to Vault

          vault login ${VAULT_TOKEN}
          vault secrets enable -path=certs kv || true
          vault kv put ${CERT_PATH}                             \
              certificate=@/etc/ssl/${DOMAIN}.pem               \
              private_key=@/etc/ssl/${DOMAIN}.key
          echo "Certificate and private key written to Vault at path: ${CERT_PATH}"

至此,已经完成SSL Certs 申请的自动化,每两个月执行一次,确保Vault中永远存储有效的证书。

流水线执行成功后,登录 Vault UI 已经看到域名证书已经保存

应用集群侧配置

将证书分到到应用集群中

接下来的的工作就是,如何在IAC流水线中,集成Vault 操作,读取域名证书并写入集群master节点 /etc/ssl/ 目录

  • playbook/roles/cert-manager/tasks/main.yml
代码语言:yaml
AI代码解释
复制
- name: Fetch Certificate and Private Key from Vault
  script: files/get_certificate.sh {{ domain }} {{ vault_url }} {{ vault_token }}
  when: (inventory_hostname in groups[group]) and (vault == true)
  • playbook/roles/cert-manager/files/get_certificate.sh
代码语言:shell
AI代码解释
复制
#!/bin/bash

sudo apt-get update
sudo apt install -y software-properties-common
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list > /dev/null
sudo apt-get update
sudo apt-get install -y python3-pip jq vault

check_empty() {
  if [ -z "$1" ]; then
    echo "$2"
    exit 1
  fi
}

check_empty "$1" "Please provide DOMAIN" && DOMAIN=$1
check_empty "$2" "Please provide VAULT_ADDR" && VAULT_ADDR=$2
check_empty "$3" "Please provide VAULT_TOKEN" && VAULT_TOKEN=$3

SECRET_PATH="certs/$DOMAIN"

# Output paths
CERTIFICATE_PATH="/etc/ssl/${DOMAIN}.pem"
PRIVATE_KEY_PATH="/etc/ssl/${DOMAIN}.key"

vault login
# Read certificate from Vault
vault kv get -field=certificate certs/${DOMAIN} > "$CERTIFICATE_PATH"
# Read private key from Vault
vault kv get -field=private_key certs/${DOMAIN} > "$PRIVATE_KEY_PATH"

# Set permissions for the private key (modify as needed)
chmod 600 "$PRIVATE_KEY_PATH"

# Check if certificate and private key files are non-empty
if [ ! -s "$CERTIFICATE_PATH" ] || [ ! -s "$PRIVATE_KEY_PATH" ]; then
    echo "Certificate or private key is empty. Exiting..."
    exit 1
else
    echo "Certificate and private key have been written to $CERTIFICATE_PATH and $PRIVATE_KEY_PATH"

验证 SSL 证书

登陆节点,执行命令:cat /etc/ssl/<domain_name>.* 验证分发的证书

验证 Secret

可以使用以下命令检查 Secret:

代码语言:bash
AI代码解释
复制
kubectl get secret my-cert-secret -o yaml

最后使用Curl 命令验证使用和证书的服务或者API接口否生效

代码语言:bash
AI代码解释
复制
curl https://your_svc.com

总结

通过以上步骤,你可以建立一个自动化流程,通过 GitHub Actions 自动续订 Let's Encrypt 证书,将其存储在 Vault 中,并更新 Kubernetes 集群的 CertManager 配置以使用这些证书。请注意,这里的示例可能需要根据你的环境和需求进行调整。在部署到生产环境之前,请确保对配置进行充分测试。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Ghost 博客 SSL 证书过期的解决办法
点击 高级 也没有进去的链接,而且页面地址前面写着”不安全“,证书显示也已经过期一个月了。而且我自己部署的 flask 服务也访问不了了。
Alan Lee
2021/12/07
8250
Ghost 博客 SSL 证书过期的解决办法
用acme.sh自动部署域名证书
目前使用量最大的免费SSL证书就是Let’s Encrypt,自2018-03开始,Let’s Encrypt官方发布上线了免费的SSL泛域名证书,目前通过DNS方式获取比较快,国内可以通过鹅云的DNSPod域名API或者猫云域名API自动签发Let’s Encrypt泛域名证书。因为鹅云使用的就是DNSPod域名,并且鹅云和DNSPod的账号是打通的,可以使用wx直接扫码登录。下文需要对鹅云和DNSPod进行操作,为了简化证书申请过程,需要提前安装acme.sh。acme.sh实现了acme协议,可以从Let’s Encrypt生成免费的证书,自动创建cron任务, 每天零点自动检测所有的证书,如果发现证书快过期了,需要更新,则acme.sh会自动更新证书,安装过程不会污染已有的系统任何功能和文件,所有的修改都限制在安装目录中。
摘繁华
2022/12/05
3.2K0
用acme.sh自动部署域名证书
使用acme.sh申请Let's Encrypt免费的SSL证书
acme.sh 实现了 acme 协议,可以从letsencrypt生成免费的证书。接下来将为大家介绍怎样申请Let's Encrypt通配符证书。
青阳
2021/09/15
5.8K4
acme.sh生成自动续费的免费SSL证书
acme.sh 实现了 acme 协议,可以从 letsencrypt 生成免费的证书。 一个完全用Shell(Unix shell)语言编写的ACME协议客户端,支持ACME v1和ACME v2,只需一个脚本即可生成发布,续订和自动安装SSL证书。
骤雨重山
2022/01/17
2.4K0
可能是最详细的部署:Docker Registry企业级私有镜像仓库Harbor管理WEB UI
上一篇文章搭建了一个具有基础功能,权限认证、TLS 的私有仓库,但是Docker Registry 作为镜像仓库,连管理界面都没有,甚至连一些运维必备的功能都是缺失的,还有什么 Docker 镜像仓库管理工具呢? 这里有一个简单好用的企业级 Registry 服务器 - Harbor,推荐在生产环境上使用。 Harbor 简介 Harbor是VMware公司开源的企业级Docker Registry项目,其目标是帮助用户迅速搭建一个企业级的Docker registry服务。 它以Docker公司开源的re
程序员鹏磊
2018/02/09
2.5K0
可能是最详细的部署:Docker Registry企业级私有镜像仓库Harbor管理WEB UI
使用 acme.sh 申请 SSL 证书
在申请 ssl 时,大部分平台都会存在或多或少的限制,比如国内平台的 亚洲诚信 ,该平台可以一次性申请双域名有效期为一年的证书,或者短期的通配符证书
阿龙w
2023/10/23
1.8K0
使用acme.sh生成免费的SSL证书
acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.
码客说
2021/03/02
4.9K0
正确使用 acme.sh, 让你的网站永久使用 ssl 证书,It's free!
acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.
用户1418987
2023/12/06
10.9K1
正确使用 acme.sh, 让你的网站永久使用 ssl 证书,It's free!
acme.sh 自动续签 SSL 证书
证书生成完成之后 acme.sh 会自动保存 API_ID 和 APK KEY,保存到 ~/.acme.sh/account.conf,下次再使用时,不需要再指定AccessKey了。
陳斯托洛夫斯記
2024/08/07
3920
40.9k star,acme.sh,ssl证书替换神器
假设你搞了博客,服务器买好了,域名买好了,服务开发好了,然后发现还需要证书,而且免费的3个月就要换?
大侠之运维
2025/01/23
2570
通过acme.sh开源工具申请泛解析SSL证书
2.Linux云服务器(本文系统某讯云的Centos7),测试公网IP为:150.158.130.33
星哥玩云
2022/06/28
2390
通过acme.sh开源工具申请泛解析SSL证书
告别焦虑:使用 acme 实现 ssl 免费证书到期自动更新
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2024/08/09
3.4K0
Ssl证书自动续签
生成的证书放在了/root/.acme.sh/plyx.site目录,因为这是 acme.sh 脚本的内部使用目录,而且目录结构可能会变化,所以我们不能让 Nginx 的配置文件直接读取该目录下的证书文件。
mikelLam
2022/10/31
1.5K0
acme申请ssl证书
acme安装的时候就会自动添加crond计划任务来处理续约,当然也是可以手动来renew的。
行 者
2024/03/11
5830
如何使用acme.sh自动获取、更新Let’s Encrypt的SSL证书?
acme.sh实现了acme协议,可以从let's encrypt生成免费的ssl证书。本文主要记录使用dnspod api 自动申请ssl证书
房东的狗丶
2023/02/17
5.5K0
手把手教你免费申请支持通配符的 SSL 证书
得益于 Google 等大厂的消灭 HTTP 运动和 Let’s Encrypt 非盈利组织的努力,越来越多的站点开始迁移到 HTTPS,下图是 Let’s Encrypt 的统计数据。
iMike
2019/07/30
6.9K0
免费泛域名SSL证书
acme.sh 官方提供一个非常简单的一键安装脚本,老少皆宜。当然,安装这个工具对于是否在公网并没有任何要求,你可以选择在将要部署 SSL 证书的内网服务器中安装即可,请用非root用户全程执行命令。
chuchur
2024/11/21
1.7K0
什么?!你还不会申请免费的SSL证书??
突然发现我的网站没有SSL,作为一个职业前端人,我得有,而且我得会弄,之前上学那会儿有用宝塔一键部署过,感觉应该不会很复杂。
HoMeTown
2022/10/26
7260
HTTPS之acme.sh申请证书
Let's Encrypt是一个于2015年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的SSL/TLS证书。 Let's Encrypt由互联网安全研究小组(缩写ISRG)提供服务。主要赞助商包括电子前哨基金会、Mozilla基金会、Akamai以及思科。2015年4月9日,ISRG与Linux基金会宣布合作。 用以实现新的数字证书认证机构的协议被称为自动证书管理环境(ACME)。GitHub上有这一规范的草案,且提案的一个版本已作为一个Internet草案发布。 Let's Encrypt宣称这一过程将十分简单、自动化并且免费
惨绿少年
2018/12/19
4.8K0
SSL证书自动化-acme实战(Let’s Encrypt)
由于 HTTP 是明文传输,在使用 NextCloud 等服务时不够安全,需要配置 SSL 证书。不想让在被别人浏览的时候,出现莫名的广告[运营商劫持]。
用户10002156
2023/12/13
2.3K0
SSL证书自动化-acme实战(Let’s Encrypt)
推荐阅读
相关推荐
Ghost 博客 SSL 证书过期的解决办法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档