@@ -76,30 +76,25 @@ cat <<EOF | cfssl genkey - | cfssljson -bare server
76
76
"192.0.2.24",
77
77
"10.0.34.2"
78
78
],
79
- "CN": "system:node: my-pod.my-namespace.pod.cluster.local",
79
+ "CN": "my-pod.my-namespace.pod.cluster.local",
80
80
"key": {
81
81
"algo": "ecdsa",
82
82
"size": 256
83
- },
84
- "names": [
85
- {
86
- "O": "system:nodes"
87
- }
88
- ]
83
+ }
89
84
}
90
85
EOF
91
86
```
92
87
93
88
Where ` 192.0.2.24 ` is the service's cluster IP,
94
89
` my-svc.my-namespace.svc.cluster.local ` is the service's DNS name,
95
90
` 10.0.34.2 ` is the pod's IP and ` my-pod.my-namespace.pod.cluster.local `
96
- is the pod's DNS name. You should see the following output:
91
+ is the pod's DNS name. You should see the output similar to :
97
92
98
93
```
99
- 2017/03/21 06:48:17 [INFO] generate received request
100
- 2017/03/21 06:48:17 [INFO] received CSR
101
- 2017/03/21 06:48:17 [INFO] generating key: ecdsa-256
102
- 2017/03/21 06:48:17 [INFO] encoded CSR
94
+ 2022/02/01 11:45:32 [INFO] generate received request
95
+ 2022/02/01 11:45:32 [INFO] received CSR
96
+ 2022/02/01 11:45:32 [INFO] generating key: ecdsa-256
97
+ 2022/02/01 11:45:32 [INFO] encoded CSR
103
98
```
104
99
105
100
This command generates two files; it generates ` server.csr ` containing the PEM
@@ -120,7 +115,7 @@ metadata:
120
115
name: my-svc.my-namespace
121
116
spec:
122
117
request: $( cat server.csr | base64 | tr -d ' \n' )
123
- signerName: kubernetes.io/kubelet- serving
118
+ signerName: example.com/ serving
124
119
usages:
125
120
- digital signature
126
121
- key encipherment
131
126
Notice that the ` server.csr ` file created in step 1 is base64 encoded
132
127
and stashed in the ` .spec.request ` field. We are also requesting a
133
128
certificate with the "digital signature", "key encipherment", and "server
134
- auth" key usages, signed by the ` kubernetes.io/kubelet- serving` signer.
129
+ auth" key usages, signed by an example ` example.com/ serving` signer.
135
130
A specific ` signerName ` must be requested.
136
131
View documentation for [ supported signer names] ( /docs/reference/access-authn-authz/certificate-signing-requests/#signers )
137
132
for more information.
@@ -147,14 +142,16 @@ kubectl describe csr my-svc.my-namespace
147
142
Name: my-svc.my-namespace
148
143
Labels: <none>
149
144
Annotations: <none>
150
- CreationTimestamp: Tue, 21 Mar 2017 07:03:51 -0700
145
+ CreationTimestamp: Tue, 01 Feb 2022 11:49:15 -0500
151
146
Requesting User: [email protected]
147
+ Signer: example.com/serving
152
148
Status: Pending
153
149
Subject:
154
- Common Name: my-svc .my-namespace.svc .cluster.local
150
+ Common Name: my-pod .my-namespace.pod .cluster.local
155
151
Serial Number:
156
152
Subject Alternative Names:
157
- DNS Names: my-svc.my-namespace.svc.cluster.local
153
+ DNS Names: my-pod.my-namespace.pod.cluster.local
154
+ my-svc.my-namespace.svc.cluster.local
158
155
IP Addresses: 192.0.2.24
159
156
10.0.34.2
160
157
Events: <none>
@@ -175,30 +172,136 @@ kubectl certificate approve my-svc.my-namespace
175
172
certificatesigningrequest.certificates.k8s.io/my-svc.my-namespace approved
176
173
```
177
174
175
+ You should now see the following:
178
176
179
- ## Download the Certificate and Use It
177
+ ``` shell
178
+ kubectl get csr
179
+ ```
180
+
181
+ ``` none
182
+ NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
183
+ my-svc.my-namespace 10m example.com/serving [email protected] <none> Approved
184
+ ```
185
+
186
+ This means the certificate request has been approved and is waiting for the
187
+ requested signer to sign it.
188
+
189
+ ## Sign the Certificate Signing Request
190
+
191
+ Next, you'll play the part of a certificate signer, issue the certificate, and upload it to the API.
192
+
193
+ A signer would typically watch the Certificate Signing Request API for objects with its ` signerName ` ,
194
+ check that they have been approved, sign certificates for those requests,
195
+ and update the API object status with the issued certificate.
196
+
197
+ ### Create a Certificate Authority
198
+
199
+ First, create a signing certificate by running the following:
200
+
201
+ ``` shell
202
+ cat << EOF | cfssl gencert -initca - | cfssljson -bare ca
203
+ {
204
+ "CN": "My Example Signer",
205
+ "key": {
206
+ "algo": "rsa",
207
+ "size": 2048
208
+ }
209
+ }
210
+ EOF
211
+ ```
212
+
213
+ You should see the output similar to:
180
214
181
- Once the CSR is signed and approved you should see the following:
215
+ ``` none
216
+ 2022/02/01 11:50:39 [INFO] generating a new CA key and certificate from CSR
217
+ 2022/02/01 11:50:39 [INFO] generate received request
218
+ 2022/02/01 11:50:39 [INFO] received CSR
219
+ 2022/02/01 11:50:39 [INFO] generating key: rsa-2048
220
+ 2022/02/01 11:50:39 [INFO] encoded CSR
221
+ 2022/02/01 11:50:39 [INFO] signed certificate with serial number 263983151013686720899716354349605500797834580472
222
+ ```
223
+
224
+ This produces a certificate authority key file (` ca-key.pem ` ) and certificate (` ca.pem ` ).
225
+
226
+ ### Issue a Certificate
227
+
228
+ {{< codenew file="tls/server-signing-config.json" >}}
229
+
230
+ Use a ` server-signing-config.json ` signing configuration and the certificate authority key file
231
+ and certificate to sign the certificate request:
232
+
233
+ ``` shell
234
+ kubectl get csr my-svc.my-namespace -o jsonpath=' {.spec.request}' | \
235
+ base64 --decode | \
236
+ cfssl sign -ca ca.pem -ca-key ca-key.pem -config server-signing-config.json - | \
237
+ cfssljson -bare ca-signed-server
238
+ ```
239
+
240
+ You should see the output similar to:
241
+
242
+ ```
243
+ 2022/02/01 11:52:26 [INFO] signed certificate with serial number 576048928624926584381415936700914530534472870337
244
+ ```
245
+
246
+ This produces a signed serving certificate file, ` ca-signed-server.pem ` .
247
+
248
+ ### Upload the Signed Certificate
249
+
250
+ Finally, populate the signed certificate in the API object's status:
251
+
252
+ ``` shell
253
+ kubectl get csr my-svc.my-namespace -o json | \
254
+ jq ' .status.certificate = "' $( base64 ca-signed-server.pem | tr -d ' \n' ) ' "' | \
255
+ kubectl replace --raw /apis/certificates.k8s.io/v1/certificatesigningrequests/my-svc.my-namespace/status -f -
256
+ ```
257
+
258
+ {{< note >}}
259
+ This uses the command line tool [ jq] ( https://stedolan.github.io/jq/ ) to populate the base64-encoded content in the ` .status.certificate ` field.
260
+ If you do not have ` jq ` , you can also save the JSON output to a file, populate this field manually, and upload the resulting file.
261
+ {{< /note >}}
262
+
263
+ Once the CSR is approved and the signed certificate is uploaded you should see the following:
182
264
183
265
``` shell
184
266
kubectl get csr
185
267
```
186
268
187
269
``` none
188
- NAME AGE REQUESTOR CONDITION
189
- my-svc.my-namespace 10m [email protected] Approved,Issued
270
+ NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
271
+ my-svc.my-namespace 20m example.com/serving [email protected] <none> Approved,Issued
190
272
```
191
273
192
- You can download the issued certificate and save it to a ` server.crt ` file
193
- by running the following:
274
+ ## Download the Certificate and Use It
275
+
276
+ Now, as the requesting user, you can download the issued certificate
277
+ and save it to a ` server.crt ` file by running the following:
194
278
195
279
``` shell
196
280
kubectl get csr my-svc.my-namespace -o jsonpath=' {.status.certificate}' \
197
281
| base64 --decode > server.crt
198
282
```
199
283
200
- Now you can use ` server.crt ` and ` server-key.pem ` as the keypair to start
201
- your HTTPS server.
284
+ Now you can populate ` server.crt ` and ` server-key.pem ` in a secret and mount
285
+ it into a pod to use as the keypair to start your HTTPS server:
286
+
287
+ ``` shell
288
+ kubectl create secret tls server --cert server.crt --key server-key.pem
289
+ ```
290
+
291
+ ``` none
292
+ secret/server created
293
+ ```
294
+
295
+ Finally, you can populate ` ca.pem ` in a configmap and use it as the trust root
296
+ to verify the serving certificate:
297
+
298
+ ``` shell
299
+ kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
300
+ ```
301
+
302
+ ``` none
303
+ configmap/example-serving-ca created
304
+ ```
202
305
203
306
## Approving Certificate Signing Requests
204
307
0 commit comments