当前位置: 首页 > article >正文

构建后端为etcd的CoreDNS的容器集群(一)、生成自签名证书

笔者拟使用官方的etcd和CoreDNS容器镜像生成带自签名的分布式DNS容器集群。按计划需做生成自签名证书、部署etcd集群、配置CoreDNS以使用etcd作为后端共三步,本文为第一步。

一、生成自签名证书

1、准备CFSSL工具

官网下载:

[root@localhost ~]# cd /opt && mkdir cfssl/
[root@localhost opt# cd cfssl
[root@localhost cfssl]# curl -s -L -o cfssl https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64 
[root@localhost cfssl]# curl -s -L -o cfssljson https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64
root@localhost cfssl]# ls 
cfssl  cfssljson
[root@localhost cfssl]# chmod a+x *

2、创建证书签名配置文件

编写一个缺省签名配置文件ca-config.json(可用“./cfssl print-defaults config > ca-config.json”来生成模板,再进行修改),设置证书请求的基础信息,包括有效期,权限等。

[root@localhost cfssl]# vi ca-config.json
[root@localhost cfssl]# cat ca-config.json
{
    "signing":{
        "default":{
            "expiry":"262800h"
        },
        "profiles":{
            "etcd":{
                "usages":[
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ],
                "expiry":"262800h"
            }
        }
    }
}

本例设置缺省和etcd的证书过期时间均为262800小时,30年,etcd证书包括签名、密钥加密、服务器身份验证和客户端身份验证权限。

编写签名请求文件ca-csr.json(可用“./cfssl print-defaults csr > ca-csr.json”来生成模板,再进行修改),设置ca证书的有效期、CN、证书请求的主机名和IP清单、证书信息等。

[root@localhost cfssl]# vi ca-csr.json
[root@localhost cfssl]# cat ca-csr.json
{
    "CA":{"expiry":"262800h"},
    "CN": "etcd",
    "hosts": [
        "etcd-1",
        "etcd-2",
        "etcd-3",
        "coredns-1",
        "coredns-2",
        "coredns-3",
        "127.0.0.1",
        "localhost"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "CQ",
            "L": "CQ",
            "O": "etcd",
            "OU": "System"
        }
    ]
}

此时主机上的文件

3、生成CA证书 

使用CFSSL工具生成CA证书。

[root@localhost cfssl]# ./cfssl gencert -initca ca-csr.json | ./cfssljson -bare ca
2024/10/14 12:22:01 [INFO] generating a new CA key and certificate from CSR
2024/10/14 12:22:01 [INFO] generate received request
2024/10/14 12:22:01 [INFO] received CSR
2024/10/14 12:22:01 [INFO] generating key: rsa-2048
2024/10/14 12:22:01 [INFO] encoded CSR
2024/10/14 12:22:01 [INFO] signed certificate with serial number 702901479885177273798408306706267990055396257030

验证证书信息:

[root@localhost cfssl]# ./cfssl certinfo -cert ca.pem     
{
  "subject": {
    "common_name": "etcd",
    "country": "CN",
    "organization": "etcd",
    "organizational_unit": "System",
    "locality": "CQ",
    "province": "CQ",
    "names": [
      "CN",
      "CQ",
      "CQ",
      "etcd",
      "System",
      "etcd"
    ]
  },
  "issuer": {
    "common_name": "etcd",
    "country": "CN",
    "organization": "etcd",
    "organizational_unit": "System",
    "locality": "CQ",
    "province": "CQ",
    "names": [
      "CN",
      "CQ",
      "CQ",
      "etcd",
      "System",
      "etcd"
    ]
  },
  "serial_number": "702901479885177273798408306706267990055396257030",
  "sans": [
    "127.0.0.1"
  ],
  "not_before": "2024-10-14T04:17:00Z",
  "not_after": "2054-10-07T04:17:00Z",
  "sigalg": "SHA256WithRSA",
  "authority_key_id": "",
  "subject_key_id": "B4:17:C4:DE:3D:A6:12:0A:E2:47:46:7A:95:BD:79:4D:6E:3A:C8:8F",
  "pem": "-----BEGIN CERTIFICATE-----\nMIIDjzCCAnegAwIBAgIUex8xRPlghlY9nsgk/EWanNxDLQYwDQYJKoZIhvcNAQEL\nBQAwVjELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAkNRMQswCQYDVQQHEwJDUTENMAsG\nA1UEChMEZXRjZDEPMA0GA1UECxMGU3lzdGVtMQ0wCwYDVQQDEwRldGNkMCAXDTI0\nMTAxNDA0MTcwMFoYDzIwNTQxMDA3MDQxNzAwWjBWMQswCQYDVQQGEwJDTjELMAkG\nA1UECBMCQ1ExCzAJBgNVBAcTAkNRMQ0wCwYDVQQKEwRldGNkMQ8wDQYDVQQLEwZT\neXN0ZW0xDTALBgNVBAMTBGV0Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDEHlH5MgjEhfyUJX1ajt3IztPkAJSn+D/A6uiCEFQnCmFDBJEB0TBWVofu\nqFFGOC8VFxX0l1dKKv3GuJf9uAdpnU2BSkmiK4aX0oY9RdyuLLmmqeLJeZ9T8YCC\nGhfHRfdF8woyXLlHXjTjArtSxUnsF9IiyXV/qkUYBdKxAxtGG4i5Ja9Fl79oczUi\nWWZwVR8w+L9IvuY5j1LU6nazyuNeGOjOF+ucZ0PxP3jvEx6h9Um7eUsfVMLPNUnG\ne8rtFRJAYRpRqnyeIz3jhFszEhTZUlDv+UiR/t6eU7kMUEXIDenPPABdUGHs6cSV\nFjidrFmK2ShoM5FReiXj02FJH3JvAgMBAAGjUzBRMA4GA1UdDwEB/wQEAwIBBjAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS0F8TePaYSCuJHRnqVvXlNbjrIjzAP\nBgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCvlGxoZiKBfH/I6XhQ\n7e9yhQla8msXyDynCknCutBoj5a8AedkTqKC4ts3Ha6iW5JELz24k5hAly/UZ3Pg\nMZPKnJScgSZXfcQ7mpLwWdspxwivYSQxPJT3FcNBU4oxjLVwNJeCTbItpGm9pLOG\nMRcRvSAtkS2GgJyxv5Qao4cPQWsmb2VNmov2bjcaeZscnxvwq+xKh8kJg5r30htR\n5+WZqLUDdB1uqtLKDj0PMVZaCGaypn92/5FOpvnWLI0hMSXpXxw1gz9mB4CxIjq9\nFmkSzzoadQ/6Zn8oTaKzhmbWpDaypKtcxFUpvDhObst0886R7JfDvULqIbXvPjnA\nQsvW\n-----END CERTIFICATE-----\n"
}2nHyN4y7jX+c\nUMqm\n-----END CERTIFICATE-----\n"
}

可以看到"subject"、issuer"、证书有效期等信息均已生效。

此时主机上的文件:

[root@localhost cfssl]# ll
总用量 18M
-rw-r--r--. 1 root root  375 10月 14 11:39 ca-config.json
-rw-r--r--. 1 root root 1.2K 10月 14 12:22 ca.csr
-rw-r--r--. 1 root root  461 10月 14 11:44 ca-csr.json
-rw-------. 1 root root 1.7K 10月 14 12:22 ca-key.pem
-rw-r--r--. 1 root root 1.3K 10月 14 12:22 ca.pem
-rwxr-xr-x. 1 root root  12M 10月 12 16:24 cfssl
-rwxr-xr-x. 1 root root 6.0M 10月 12 16:25 cfssljsonfssljson

4、生成服务器证书 

使用CFSSL工具生成服务器证书。因为已完成CA的初始化,需要删掉ca-csr.json文件中的"CA":{"expiry":"262800h"}这一行。否则执行下一步时会报错“ca section only permitted in initca”,无法执行。


[root@localhost cfssl]# vi ca-csr.json
[root@localhost cfssl]# head -3 ca-csr.json 
{
    "CN": "etcd",
    "hosts": [
[root@localhost cfssl]# ./cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd ca-csr.json | ./cfssljson -bare etcd
2024/10/14 12:35:48 [INFO] generate received request
2024/10/14 12:35:48 [INFO] received CSR
2024/10/14 12:35:48 [INFO] generating key: rsa-2048
2024/10/14 12:35:48 [INFO] encoded CSR
2024/10/14 12:35:48 [INFO] signed certificate with serial number 440635272983453598154344122362845954472854373569

5、验证服务器证书

[root@localhost cfssl]# ./cfssl certinfo -cert etcd.pem   
{
  "subject": {
    "common_name": "etcd",
    "country": "CN",
    "organization": "etcd",
    "organizational_unit": "System",
    "locality": "CQ",
    "province": "CQ",
    "names": [
      "CN",
      "CQ",
      "CQ",
      "etcd",
      "System",
      "etcd"
    ]
  },
  "issuer": {
    "common_name": "etcd",
    "country": "CN",
    "organization": "etcd",
    "organizational_unit": "System",
    "locality": "CQ",
    "province": "CQ",
    "names": [
      "CN",
      "CQ",
      "CQ",
      "etcd",
      "System",
      "etcd"
    ]
  },
  "serial_number": "440635272983453598154344122362845954472854373569",
  "sans": [
    "etcd-1",
    "etcd-2",
    "etcd-3",
    "coredns-1",
    "coredns-2",
    "coredns-3",
    "localhost",
    "127.0.0.1"
  ],
  "not_before": "2024-10-14T04:31:00Z",
  "not_after": "2054-10-07T04:31:00Z",
  "sigalg": "SHA256WithRSA",
  "authority_key_id": "",
  "subject_key_id": "9B:C1:C1:C2:5B:6F:B3:0F:6D:27:88:7D:73:FD:BA:EB:9E:31:7C:60",
  "pem": "-----BEGIN CERTIFICATE-----\nMIID8TCCAtmgAwIBAgIUTS7E3WmnukrPsDt9Nj4xup5LRMEwDQYJKoZIhvcNAQEL\nBQAwVjELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAkNRMQswCQYDVQQHEwJDUTENMAsG\nA1UEChMEZXRjZDEPMA0GA1UECxMGU3lzdGVtMQ0wCwYDVQQDEwRldGNkMCAXDTI0\nMTAxNDA0MzEwMFoYDzIwNTQxMDA3MDQzMTAwWjBWMQswCQYDVQQGEwJDTjELMAkG\nA1UECBMCQ1ExCzAJBgNVBAcTAkNRMQ0wCwYDVQQKEwRldGNkMQ8wDQYDVQQLEwZT\neXN0ZW0xDTALBgNVBAMTBGV0Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDdOAXtT+aiO8R/g/hGEhjdaomujyDDcQjN7UBESHilHTUl1sWAR8R2QfCV\n4rU0vjXmZyLnR4+c6CZdLajuQbRpc75UBYLbL2vD6xhaH53ZoUkiBhlgt19YLkZS\nusa336oCIEaSnkC3yrj9AOLnK9BgfS6HxE1NmYp1QiDv4qnix9c15z4+zRPwgaW9\nkOHdftHZlUTxh/dWw38DgPRQ3sGyQLA+Mxc/hQZaTqFHzCEt+/E0PS8awsDRGysV\nwXLto+kEI9S5EkOcmjGbwgym91ZJ2C+KbJ2Hr0XTW4ab6DML1mx0pp52JNJniZ+A\nU8TBlaT2U5XtfwLsBsK63CGGbTrXAgMBAAGjgbQwgbEwDgYDVR0PAQH/BAQDAgWg\nMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0G\nA1UdDgQWBBSbwcHCW2+zD20niH1z/brrnjF8YDBTBgNVHREETDBKggZldGNkLTGC\nBmV0Y2QtMoIGZXRjZC0zggljb3JlZG5zLTGCCWNvcmVkbnMtMoIJY29yZWRucy0z\ngglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQADggEBAJyBV4HIyFYJXhGl\neBalIzpw2TFNqIgQ30x83NvF7UX1x5GSAh8xfk7cR3oVQfyXWmkDafkf859DktDP\nSk8znsMXSOomQUHBuIIzL/xRNGmReAQ0FAnecagFPXX5/fEjK/T0oYmZDkLZBAuq\nQHTtFUXXlonxnJTgy53OzZkzgbAjCKWvgRqvVgCj5YGMPNVKk3QKnt0OTMS01ePV\nEOUaK9ko+Fvs9n2h4mZG7+txv8NkIAB6whfLNj7oQubOnr45OQjRBpFF2qgnRiZk\ngsqRwB46PpO2pf/mcwc0+t/1Zx99+wUpzfFdbCs4eRVxjAZFMtRJE1rujitWVwE6\n2nQB0qA=\n-----END CERTIFICATE-----\n"
}

可以看到服务器证书有效期为30年、授权的主机列表等的。

此时当前目录的全部文件:

[root@localhost cfssl]# ll
总用量 18M
-rw-r--r--. 1 root root  375 10月 14 11:39 ca-config.json
-rw-r--r--. 1 root root 1.2K 10月 14 12:22 ca.csr
-rw-r--r--. 1 root root  430 10月 14 12:35 ca-csr.json
-rw-------. 1 root root 1.7K 10月 14 12:22 ca-key.pem
-rw-r--r--. 1 root root 1.3K 10月 14 12:22 ca.pem
-rwxr-xr-x. 1 root root  12M 10月 12 16:24 cfssl
-rwxr-xr-x. 1 root root 6.0M 10月 12 16:25 cfssljson
-rw-r--r--. 1 root root 1.1K 10月 14 12:35 etcd.csr
-rw-------. 1 root root 1.7K 10月 14 12:35 etcd-key.pem
-rw-r--r--. 1 root root 1.4K 10月 14 12:35 etcd.pem

后期需要用到的3个证书内容如下:

[root@localhost cfssl]# cat ca.pem
-----BEGIN CERTIFICATE-----
MIIDjzCCAnegAwIBAgIUex8xRPlghlY9nsgk/EWanNxDLQYwDQYJKoZIhvcNAQEL
BQAwVjELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAkNRMQswCQYDVQQHEwJDUTENMAsG
A1UEChMEZXRjZDEPMA0GA1UECxMGU3lzdGVtMQ0wCwYDVQQDEwRldGNkMCAXDTI0
MTAxNDA0MTcwMFoYDzIwNTQxMDA3MDQxNzAwWjBWMQswCQYDVQQGEwJDTjELMAkG
A1UECBMCQ1ExCzAJBgNVBAcTAkNRMQ0wCwYDVQQKEwRldGNkMQ8wDQYDVQQLEwZT
eXN0ZW0xDTALBgNVBAMTBGV0Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDEHlH5MgjEhfyUJX1ajt3IztPkAJSn+D/A6uiCEFQnCmFDBJEB0TBWVofu
qFFGOC8VFxX0l1dKKv3GuJf9uAdpnU2BSkmiK4aX0oY9RdyuLLmmqeLJeZ9T8YCC
GhfHRfdF8woyXLlHXjTjArtSxUnsF9IiyXV/qkUYBdKxAxtGG4i5Ja9Fl79oczUi
WWZwVR8w+L9IvuY5j1LU6nazyuNeGOjOF+ucZ0PxP3jvEx6h9Um7eUsfVMLPNUnG
e8rtFRJAYRpRqnyeIz3jhFszEhTZUlDv+UiR/t6eU7kMUEXIDenPPABdUGHs6cSV
FjidrFmK2ShoM5FReiXj02FJH3JvAgMBAAGjUzBRMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS0F8TePaYSCuJHRnqVvXlNbjrIjzAP
BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCvlGxoZiKBfH/I6XhQ
7e9yhQla8msXyDynCknCutBoj5a8AedkTqKC4ts3Ha6iW5JELz24k5hAly/UZ3Pg
MZPKnJScgSZXfcQ7mpLwWdspxwivYSQxPJT3FcNBU4oxjLVwNJeCTbItpGm9pLOG
MRcRvSAtkS2GgJyxv5Qao4cPQWsmb2VNmov2bjcaeZscnxvwq+xKh8kJg5r30htR
5+WZqLUDdB1uqtLKDj0PMVZaCGaypn92/5FOpvnWLI0hMSXpXxw1gz9mB4CxIjq9
FmkSzzoadQ/6Zn8oTaKzhmbWpDaypKtcxFUpvDhObst0886R7JfDvULqIbXvPjnA
QsvW
-----END CERTIFICATE-----
[root@localhost cfssl]# cat etcd.pem
-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIUTS7E3WmnukrPsDt9Nj4xup5LRMEwDQYJKoZIhvcNAQEL
BQAwVjELMAkGA1UEBhMCQ04xCzAJBgNVBAgTAkNRMQswCQYDVQQHEwJDUTENMAsG
A1UEChMEZXRjZDEPMA0GA1UECxMGU3lzdGVtMQ0wCwYDVQQDEwRldGNkMCAXDTI0
MTAxNDA0MzEwMFoYDzIwNTQxMDA3MDQzMTAwWjBWMQswCQYDVQQGEwJDTjELMAkG
A1UECBMCQ1ExCzAJBgNVBAcTAkNRMQ0wCwYDVQQKEwRldGNkMQ8wDQYDVQQLEwZT
eXN0ZW0xDTALBgNVBAMTBGV0Y2QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDdOAXtT+aiO8R/g/hGEhjdaomujyDDcQjN7UBESHilHTUl1sWAR8R2QfCV
4rU0vjXmZyLnR4+c6CZdLajuQbRpc75UBYLbL2vD6xhaH53ZoUkiBhlgt19YLkZS
usa336oCIEaSnkC3yrj9AOLnK9BgfS6HxE1NmYp1QiDv4qnix9c15z4+zRPwgaW9
kOHdftHZlUTxh/dWw38DgPRQ3sGyQLA+Mxc/hQZaTqFHzCEt+/E0PS8awsDRGysV
wXLto+kEI9S5EkOcmjGbwgym91ZJ2C+KbJ2Hr0XTW4ab6DML1mx0pp52JNJniZ+A
U8TBlaT2U5XtfwLsBsK63CGGbTrXAgMBAAGjgbQwgbEwDgYDVR0PAQH/BAQDAgWg
MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0G
A1UdDgQWBBSbwcHCW2+zD20niH1z/brrnjF8YDBTBgNVHREETDBKggZldGNkLTGC
BmV0Y2QtMoIGZXRjZC0zggljb3JlZG5zLTGCCWNvcmVkbnMtMoIJY29yZWRucy0z
gglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQADggEBAJyBV4HIyFYJXhGl
eBalIzpw2TFNqIgQ30x83NvF7UX1x5GSAh8xfk7cR3oVQfyXWmkDafkf859DktDP
Sk8znsMXSOomQUHBuIIzL/xRNGmReAQ0FAnecagFPXX5/fEjK/T0oYmZDkLZBAuq
QHTtFUXXlonxnJTgy53OzZkzgbAjCKWvgRqvVgCj5YGMPNVKk3QKnt0OTMS01ePV
EOUaK9ko+Fvs9n2h4mZG7+txv8NkIAB6whfLNj7oQubOnr45OQjRBpFF2qgnRiZk
gsqRwB46PpO2pf/mcwc0+t/1Zx99+wUpzfFdbCs4eRVxjAZFMtRJE1rujitWVwE6
2nQB0qA=
-----END CERTIFICATE-----
[root@localhost cfssl]# cat etcd-key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3TgF7U/mojvEf4P4RhIY3WqJro8gw3EIze1AREh4pR01JdbF
gEfEdkHwleK1NL415mci50ePnOgmXS2o7kG0aXO+VAWC2y9rw+sYWh+d2aFJIgYZ
YLdfWC5GUrrGt9+qAiBGkp5At8q4/QDi5yvQYH0uh8RNTZmKdUIg7+Kp4sfXNec+
Ps0T8IGlvZDh3X7R2ZVE8Yf3VsN/A4D0UN7BskCwPjMXP4UGWk6hR8whLfvxND0v
GsLA0RsrFcFy7aPpBCPUuRJDnJoxm8IMpvdWSdgvimydh69F01uGm+gzC9ZsdKae
diTSZ4mfgFPEwZWk9lOV7X8C7AbCutwhhm061wIDAQABAoIBAGJFNdTS7rhY5pRi
0pKGDYemgR0LNdm8R9X6s9bhfr6Sd/6kJr4yo2KJLk/XEvooGReN72JgVrq0If64
ftfAVl2V7hGzFQs7SJsSv5Ghg+SekjdMEE/3haJNhC3SDN63u/UP02nkZQmAQ6cY
krNwsjN6yIXFPTXgpDIsuyb1QNSdcEPkxD89TLa5DxpPMresaSSbqgkscrZcQadM
TwQXNTQA1SWG4UpSCMPGm7tLCAIfsZuVg9K9gb5reTCk7M7Rc48fFig6uaJVzpPw
UPh8mT9sVrG/xxTd7bExUXkhiyyxX215Q66dE5EGj1JgLVGzZEpeUI67FJA8/Ich
8iIcnGkCgYEA9WzxZjzF+w3pZ0WhY7j/SaaAryNRz0bGXP4Z3VjbZxplxKsmHAFN
cDy4ePjxRT4LT+X7rIIwWCo3DySCNA0ud4NCblw+s4DzUCOjWagkHGR/7UduicMd
Q1dqbHEFaVPFI61wBgRC+x7ZOU/v/xKkCS0q+ymc5QUztax+lu4UIKsCgYEA5sAU
K7Pk7UCh6w+DHWQJn701JmVCTRNCm9tD8udkSfRRDqOXOQyudmrVJfqJr3ESkN5X
mqt7wwEDDChGT7xgopLtb3p/Ae2h7k0Il/UqP0k201nKF7Oboit5WVE1ALpbljjp
49TBpaLNSn2ZecfOF6aPc6/vNRz8h/oXthYcxoUCgYACIIeXEz/EBULYmknjy16r
DL5gxjWXTk250Jn4ySRdqGTpZ3JVG83IAz62DbJJn1gJwTyFKjuxB+yiPPbD7LlS
X9jbjAEfHSb+stBfno1xkY1qSQw0NXSzeLZ7ah9Z4lf7Dy3BX5gVBRds37x8wXSa
f8G3m4y4j2r7UBtow3d5MQKBgQCl+duIY+lyzl6pWYsSBPb3M32blJJQJl5vBRSn
D9GPcHEtenY3zuteuhF/M+r9ivOzyHpzAo4PAhdTE1Uf3XwU9GJdIVth46/qXPal
du9gfiU1eQxoaAS2bVbn7AWX9HQUZfO2sT5pCeVog1d1xUZ0tJXSvOXu6l6q4DVW
ACnKkQKBgQDB128IdLKy43SWu9M7UnrTKYNF10R4JByhqU93Xb1VCqDS4uv5EaU6
VjyeazHVtwMm6UCGdGXB/W97VYEITcEqxD2EAPbMM1whEhKTue+6ANgIaBlQefI1
jWKDfjv9YzT+4Qkm6ehp0tIRsSXm1K58rAczGPhdWfz2ceOUnZqx/g==
-----END RSA PRIVATE KEY-----


http://www.kler.cn/news/363949.html

相关文章:

  • STM32之OLED驱动函数
  • Java【多线程】单例模式
  • qt项目使用其他项目的ui之单继承之成员变量
  • 【Android】JNI报错 non-zero capacity for nullptr pointer分析
  • 【机器学习】VQ-VAE(Vector Quantized Variational Autoencoder)
  • Spring Boot集成:高效论坛网站的构建
  • java的maven打包插件来了,package一键打包exe、dmg、rpm等
  • 小程序开发语言Java跟php的区别
  • Element Plus的el-tree-v2 组件实现仅叶子节点显示勾选框,并且只能单选
  • MYSQL-SQL-04-DCL(Data Control Language,数据控制语言)
  • 若依框架vue3模板
  • 单例模式是一种常见的设计模式,确保一个类只有一个实例,并提供一个全局访问点。
  • Linux Redis查询key与移除日常操作
  • 尚硅谷redis 第97节 redisTmplate下答疑
  • 代码随想录算法训练营第二天| 209.长度最小的子数组 59.螺旋矩阵II 区间和 开发商购买土地
  • 身份证识别JAVA+OPENCV+OCR
  • ref属性的作用对象类型
  • 文件操作(1) —— 文件基础知识
  • 【C++】——list 容器的解析与极致实现
  • 修改IDEA中@author变量user内容
  • 开源软件搜索工具:Reddo
  • React是如何处理事件的?
  • linux 将已经启动的java应用的控制台日志输出出来, 不停应用的情况下
  • Java 使用 itextpdf 自定义 生成 pdf
  • CSS 网格布局
  • 前端发送请求格式