> For the complete documentation index, see [llms.txt](https://renhongcai.gitbook.io/kubernetes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://renhongcai.gitbook.io/kubernetes/di-qi-zhang-ji-qun-ren-zheng/7.1-zheng-shu/1.2-certificate-sign.md).

# 7.1.2 证书签发流程

对于网站类的应用，网站管理员需要向权威证书签发机构（CA）申请证书，这通常需要花费一定的费用，也有非营利的证书签发机构，比如”Let's Encrypt“可以为用户免费签发证书。但对于`Kubernetes`这类应用来讲，它通常部署在企业内部，其管理面组件不需要暴露到公网，所以就不需要向外部的证书签发机构申请证书，系统管理员就可以自已签发证书供内部使用。

本节我们使用简单的例子，介绍一下如何使用`openssl`签发证书，侧重介绍签发证书流程，具体证书配置还需要管理员根据实际情况填写。

以`kube-apiserver`为例，它的启动参数有3处需要配置证书：

```
--client-ca-file=/yourdirectory/ca.crt
--tls-cert-file=/yourdirectory/server.crt
--tls-private-key-file=/yourdirectory/server.key
```

其中`ca.crt`即CA的证书，通常Kubernetes各个组件都配置相同的CA证书，`server.crt`即`kube-apiserver`的证书，它将在与客户端建立连接时发送给客户端，由客户端进行验证，`server.key`即`kube-apiserver`的私钥，它不会发送给客户端，仅用于解密客户端发送的数据。

为了便于理解，我们假设有两位管理员参与证书签发流程，一位CA管理员负责管理CA的凭证并为他人提供签发证书的服务，一位管理员负责为`kube-apiserver`申请证书。

## 生成CA凭证

CA凭证包括一个私钥和证书，私钥由CA机构保存，不会对外公开，证书则是对外公开的。生成证书前面要先为CA机构创建一个私钥。

### 生成CA私钥

使用`openssl genrsa` 命令便可以生成一个私钥：

```
# openssl genrsa -out ca.key 2048
Generating RSA private key, 2048 bit long modulus
.....................................................................+++
........................................+++
e is 65537 (0x10001)
```

生成的私钥存在`ca.key`文件中，可以使用`cat`命令查看：

```
# ls
ca.key
# cat ca.key 
-----BEGIN RSA PRIVATE KEY-----
MIIEog...// 省略若干内容
-----END RSA PRIVATE KEY-----
```

### 生成CA证书

接着使用`openssl req`命令生成一个证书：

```
# openssl req -x509 -new -nodes -key ca.key -subj "/CN=ca" -days 10000 -out ca.crt
```

生成的证书存在`ca.crt`文件中，可以使用`openssl x509`命令查看：

```
# openssl x509 -in ca.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
...
```

到此为止，CA管理员已经拥有了一个私钥和证书，可以为`kube-apiserver`签发证书了。

## 生成kube-apiserver凭证

要申请证书，`kube-apiserver`管理员需要准备一个证书签发请求（申请书），为此，`kube-apiserver`管理员需要先为`kube-apiserver`生成一个私钥。

### 生成kube-apiserver私钥

为`kube-apiserver`生成私钥与前面为CA生成私钥的方法完全一致，同样可以使用`openssl genrsa`完成：

```
# openssl genrsa -out server.key 2048
```

生成的私钥存放于`server.key`中。

### 生成kube-apiserver证书请求

接着`kube-apiserver`管理员需要使用`kube-apiserver`的私钥生成一个证书签发请求，才可以提交给CA管理员进行签发。

使用`openssl req -new`命令可以创建一个证书请求文件：

```
# openssl req -new -key server.key -out server.csr
```

创建证书请求文件需要提供私钥，然后根据命令行提示输入相关信息，生成的请求文件存放于`server.csr`文件中。

### 生成kube-apiserver证书

当`kube-apiserver`管理员创建好证书请求文件后，即可提次给CA管理员进行证书签发了。CA管理员在签发时 需要使用CA的私钥和证书：

```
# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000 
Signature ok
```

这样签发完的证书就会保存在`server.crt`文件中。

## 证书文件后缀

关于证书及私钥文件，常常会使用约定俗成的文件名后缀。

* \*.key： 往往表示私钥文件；
* \*.crt： certificate的缩写，往往表示证书文件；

此外，`*.csr`文件为证书签名请求文件，“Certificate Signing Request”的缩写，该文件内含公钥及公钥所属者信息，用于向CA机构申请签名。

## 参考资料

* 《Self-signed\_certificate》by Wikipedia： <https://en.wikipedia.org/wiki/Self-signed_certificate>
* 《Certificates》by k8s.io：  <https://kubernetes.io/docs/concepts/cluster-administration/certificates/>
