2017-08-29 00:19:25 +03:00
# Provisioning a CA and Generating TLS Certificates
In this lab you will provision a [PKI Infrastructure ](https://en.wikipedia.org/wiki/Public_key_infrastructure ) using CloudFlare's PKI toolkit, [cfssl ](https://github.com/cloudflare/cfssl ), then use it to bootstrap a Certificate Authority, and generate TLS certificates for the following components: etcd, kube-apiserver, kubelet, and kube-proxy.
## Certificate Authority
In this section you will provision a Certificate Authority that can be used to generate additional TLS certificates.
Create the CA configuration file:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cat > ca-config.json < < EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
EOF
```
2017-10-11 08:28:21 +03:00
#### Windows
```
New-Item ca-config.json -Value @"
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
"@
```
2017-08-29 00:19:25 +03:00
Create the CA certificate signing request:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cat > ca-csr.json < < EOF
{
"CN": "Kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "CA",
"ST": "Oregon"
}
]
}
EOF
```
2017-10-11 08:28:21 +03:00
#### Windows
```
New-Item ca-csr.json -Value @"
{
"CN": "Kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "CA",
"ST": "Oregon"
}
]
}
"@
```
2017-08-29 00:19:25 +03:00
Generate the CA certificate and private key:
```
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
```
Results:
```
ca-key.pem
ca.pem
```
## Client and Server Certificates
In this section you will generate client and server certificates for each Kubernetes component and a client certificate for the Kubernetes `admin` user.
### The Admin Client Certificate
Create the `admin` client certificate signing request:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cat > admin-csr.json < < EOF
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:masters",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
```
2017-10-11 08:28:21 +03:00
#### Windows
```
New-Item admin-csr.json -Value @"
{
"CN": "admin",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:masters",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
"@
```
2017-08-29 00:19:25 +03:00
Generate the `admin` client certificate and private key:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
admin-csr.json | cfssljson -bare admin
```
2017-10-11 08:28:21 +03:00
#### Windows
```
cfssl gencert `
2017-10-24 23:22:27 +03:00
-ca ca.pem `
-ca-key ca-key.pem `
-config ca-config.json `
-profile kubernetes `
2017-10-11 08:28:21 +03:00
admin-csr.json | cfssljson -bare admin
```
2017-08-29 00:19:25 +03:00
Results:
```
admin-key.pem
admin.pem
```
### The Kubelet Client Certificates
Kubernetes uses a [special-purpose authorization mode ](https://kubernetes.io/docs/admin/authorization/node/ ) called Node Authorizer, that specifically authorizes API requests made by [Kubelets ](https://kubernetes.io/docs/concepts/overview/components/#kubelet ). In order to be authorized by the Node Authorizer, Kubelets must use a credential that identifies them as being in the `system:nodes` group, with a username of `system:node:<nodeName>` . In this section you will create a certificate for each Kubernetes worker node that meets the Node Authorizer requirements.
Generate a certificate and private key for each Kubernetes worker node:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
for instance in worker-0 worker-1 worker-2; do
cat > ${instance}-csr.json < < EOF
{
"CN": "system:node:${instance}",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:nodes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
INTERNAL_IP=$(gcloud compute instances describe ${instance} \
--format 'value(networkInterfaces[0].networkIP)')
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
-profile=kubernetes \
${instance}-csr.json | cfssljson -bare ${instance}
done
```
2017-10-11 08:28:21 +03:00
#### Windows
```
2017-10-24 23:22:27 +03:00
@('worker-0', 'worker-1', 'worker-2') | ForEach-Object {
New-Item $_-csr.json -Value @"
{
"CN": "system:node:$_",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:nodes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
"@
2017-10-11 08:28:21 +03:00
2017-10-24 23:22:27 +03:00
$EXTERNAL_IP=$(gcloud compute instances describe $_ `
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
2017-10-11 08:28:21 +03:00
2017-10-24 23:22:27 +03:00
$INTERNAL_IP=$(gcloud compute instances describe $_ `
--format 'value(networkInterfaces[0].networkIP)')
2017-10-11 08:28:21 +03:00
2017-10-24 23:22:27 +03:00
cfssl gencert `
-ca ca.pem `
-ca-key ca-key.pem `
-config ca-config.json `
-hostname $_,$EXTERNAL_IP,$INTERNAL_IP `
-profile kubernetes `
$_-csr.json | cfssljson -bare $_
}
2017-10-11 08:28:21 +03:00
```
2017-08-29 00:19:25 +03:00
Results:
```
worker-0-key.pem
worker-0.pem
worker-1-key.pem
worker-1.pem
worker-2-key.pem
worker-2.pem
```
### The kube-proxy Client Certificate
Create the `kube-proxy` client certificate signing request:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cat > kube-proxy-csr.json < < EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:node-proxier",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
```
2017-10-11 08:28:21 +03:00
#### Windows
```
New-Item kube-proxy-csr.json -Value @"
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "system:node-proxier",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
"@
```
2017-08-29 00:19:25 +03:00
Generate the `kube-proxy` client certificate and private key:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare kube-proxy
```
2017-10-11 08:28:21 +03:00
#### Windows
```
cfssl gencert `
2017-10-24 22:48:32 +03:00
-ca ca.pem `
-ca-key ca-key.pem `
-config ca-config.json `
-profile kubernetes `
2017-10-11 08:28:21 +03:00
kube-proxy-csr.json | cfssljson -bare kube-proxy
```
2017-08-29 00:19:25 +03:00
Results:
```
kube-proxy-key.pem
kube-proxy.pem
```
### The Kubernetes API Server Certificate
The `kubernetes-the-hard-way` static IP address will be included in the list of subject alternative names for the Kubernetes API Server certificate. This will ensure the certificate can be validated by remote clients.
Retrieve the `kubernetes-the-hard-way` static IP address:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
--region $(gcloud config get-value compute/region) \
--format 'value(address)')
```
2017-10-11 08:28:21 +03:00
#### Windows
```
$KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way `
--region $(gcloud config get-value compute/region) `
--format 'value(address)')
```
2017-08-29 00:19:25 +03:00
Create the Kubernetes API Server certificate signing request:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cat > kubernetes-csr.json < < EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF
```
2017-10-11 08:28:21 +03:00
#### Windows
```
New-Item kubernetes-csr.json -Value @"
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
"@
```
2017-08-29 00:19:25 +03:00
Generate the Kubernetes API Server certificate and private key:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,kubernetes.default \
-profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes
```
2017-10-11 08:28:21 +03:00
#### Windows
```
cfssl gencert `
2017-10-24 22:48:32 +03:00
-ca ca.pem `
-ca-key ca-key.pem `
-config ca-config.json `
-hostname 10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,$KUBERNETES_PUBLIC_ADDRESS,127.0.0.1,kubernetes.default `
-profile kubernetes `
2017-10-11 08:28:21 +03:00
kubernetes-csr.json | cfssljson -bare kubernetes
```
2017-08-29 00:19:25 +03:00
Results:
```
kubernetes-key.pem
kubernetes.pem
```
## Distribute the Client and Server Certificates
Copy the appropriate certificates and private keys to each worker instance:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
for instance in worker-0 worker-1 worker-2; do
gcloud compute scp ca.pem ${instance}-key.pem ${instance}.pem ${instance}:~/
done
```
2017-10-11 08:28:21 +03:00
#### Windows
```
@('worker-0','worker-1','worker-2') | ForEach-Object {
gcloud compute scp ca.pem "$_-key.pem" "$_.pem" ${_}:/home/$env:USERNAME/
}
```
2017-08-29 00:19:25 +03:00
Copy the appropriate certificates and private keys to each controller instance:
2017-10-11 08:28:21 +03:00
#### Linux & OS X
2017-08-29 00:19:25 +03:00
```
for instance in controller-0 controller-1 controller-2; do
gcloud compute scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem ${instance}:~/
done
```
2017-10-11 08:28:21 +03:00
#### Windows
```
@('controller-0', 'controller-1', 'controller-2') | ForEach-Object {
gcloud compute scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem ${_}:/home/$env:USERNAME/
}
```
2017-08-29 00:19:25 +03:00
> The `kube-proxy` and `kubelet` client certificates will be used to generate client authentication configuration files in the next lab.
Next: [Generating Kubernetes Configuration Files for Authentication ](05-kubernetes-configuration-files.md )