CA install WIP
parent
79a3f79b27
commit
397ca24343
|
@ -1,72 +1,56 @@
|
||||||
# Installing the Client Tools
|
# Installing the Client Tools
|
||||||
|
|
||||||
In this lab you will install the command line utilities required to complete this tutorial: [cfssl](https://github.com/cloudflare/cfssl), [cfssljson](https://github.com/cloudflare/cfssl), and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl).
|
In this lab you will install the command line utilities required to complete this tutorial: [step](https://github.com/smallstep/cli), and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl).
|
||||||
|
|
||||||
|
|
||||||
## Install CFSSL
|
## Install CFSSL
|
||||||
|
|
||||||
The `cfssl` and `cfssljson` command line utilities will be used to provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) and generate TLS certificates.
|
The `step` command line utility will be used to provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) and generate TLS certificates.
|
||||||
|
|
||||||
Download and install `cfssl` and `cfssljson`:
|
Download and install `step`:
|
||||||
|
|
||||||
### OS X
|
### OS X
|
||||||
|
|
||||||
```
|
For Intel chips:
|
||||||
curl -o cfssl https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssl
|
|
||||||
curl -o cfssljson https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/darwin/cfssljson
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
```
|
||||||
chmod +x cfssl cfssljson
|
curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_darwin_0.18.0_amd64.tar.gz | tar xz
|
||||||
|
sudo mv step_0.18.0/bin/step /usr/local/bin/
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
For Apple Silicon:
|
||||||
sudo mv cfssl cfssljson /usr/local/bin/
|
|
||||||
```
|
|
||||||
|
|
||||||
Some OS X users may experience problems using the pre-built binaries in which case [Homebrew](https://brew.sh) might be a better option:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
brew install cfssl
|
curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_darwin_0.18.0_arm64.tar.gz | tar xz
|
||||||
|
sudo mv step_0.18.0/bin/step /usr/local/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, if you'd like to use [Homebrew](https://brew.sh):
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install step
|
||||||
```
|
```
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
```
|
```
|
||||||
wget -q --show-progress --https-only --timestamping \
|
curl -L https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_linux_0.18.0_amd64.tar.gz
|
||||||
https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssl \
|
sudo mv step_0.18.0/bin/step /usr/local/bin/
|
||||||
https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssljson
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
chmod +x cfssl cfssljson
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo mv cfssl cfssljson /usr/local/bin/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Verification
|
### Verification
|
||||||
|
|
||||||
Verify `cfssl` and `cfssljson` version 1.4.1 or higher is installed:
|
Verify `step` version 0.18.0 or higher is installed:
|
||||||
|
|
||||||
```
|
```
|
||||||
cfssl version
|
step version
|
||||||
```
|
```
|
||||||
|
|
||||||
> output
|
> output
|
||||||
|
|
||||||
```
|
```
|
||||||
Version: 1.4.1
|
Smallstep CLI/0.18.0 (linux/amd64)
|
||||||
Runtime: go1.12.12
|
Release Date: 2021-11-17 21:15 UTC
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
cfssljson --version
|
|
||||||
```
|
|
||||||
```
|
|
||||||
Version: 1.4.1
|
|
||||||
Runtime: go1.12.12
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install kubectl
|
## Install kubectl
|
||||||
|
|
|
@ -1,100 +1,280 @@
|
||||||
# Provisioning a CA and Generating TLS Certificates
|
# Provisioning a CA
|
||||||
|
|
||||||
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, kube-controller-manager, kube-scheduler, kubelet, and kube-proxy.
|
In this lab you will provision a [PKI Infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) using Smallstep's CA server, [`step-ca`](https://github.com/smallstep/certificates), and generate TLS certificates for the following components: etcd, kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, and kube-proxy.
|
||||||
|
|
||||||
## Certificate Authority
|
## Certificate Authority
|
||||||
|
|
||||||
In this section you will provision a Certificate Authority that can be used to generate additional TLS certificates.
|
In this section you will provision a `step-ca` Certificate Authority that can be used to generate additional TLS certificates. The CA will only run on `controller-0`. While it's possible to run a high-availability CA across multiple nodes, it's not necessary in a small-to-medium sized Kubernetes cluster. The CA service would have to be down for several days before having any negative impact on the cluster.
|
||||||
|
|
||||||
Generate the CA configuration file, certificate, and private key:
|
Connect to `controller-0`:
|
||||||
|
|
||||||
|
```
|
||||||
|
gcloud compute ssh controller-0
|
||||||
|
```
|
||||||
|
|
||||||
|
Download the `step` client and `step-ca` server binaries, and the `jq` command:
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
wget -q --show-progress --https-only --timestamping \
|
||||||
cat > ca-config.json <<EOF
|
"https://dl.step.sm/gh-release/certificates/gh-release-header/v0.18.0/step-ca_linux_0.18.0_amd64.tar.gz"
|
||||||
{
|
wget -q --show-progress --https-only --timestamping \
|
||||||
"signing": {
|
"https://dl.step.sm/gh-release/cli/gh-release-header/v0.18.0/step_linux_0.18.0_amd64.tar.gz"
|
||||||
"default": {
|
sudo apt update
|
||||||
"expiry": "8760h"
|
sudo apt install -y jq
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"kubernetes": {
|
|
||||||
"usages": ["signing", "key encipherment", "server auth", "client auth"],
|
|
||||||
"expiry": "8760h"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the binaries:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
tar -xvf step-ca_linux_0.18.0_amd64.tar.gz
|
||||||
|
sudo mv step-ca_0.18.0/bin/* /usr/local/bin/
|
||||||
|
tar -xvf step_linux_0.18.0_amd64.tar.gz
|
||||||
|
sudo mv step_0.18.0/bin/* /usr/local/bin/
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now create a `step` user and the paths for `step-ca`:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
sudo useradd --system --home /etc/step-ca --shell /bin/false step
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a CA configuration folder and generate passwords for the CA root key and the CA provisioner:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
export STEPPATH=/etc/step-ca
|
||||||
|
umask 077
|
||||||
|
sudo mkdir -p $(step path)/db
|
||||||
|
< /dev/urandom tr -dc A-Za-z0-9 | head -c40 | sudo tee $(step path)/password > /dev/null
|
||||||
|
< /dev/urandom tr -dc A-Za-z0-9 | head -c40 > provisioner-password
|
||||||
|
umask 002
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Initialize your PKI:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
|
||||||
|
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
|
||||||
|
EXTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip)
|
||||||
|
INTERNAL_HOSTNAME=$(hostname -f)
|
||||||
|
sudo -E step ca init --name="admin" \
|
||||||
|
--dns="$INTERNAL_IP,$INTERNAL_HOSTNAME,$EXTERNAL_IP" \
|
||||||
|
--address=":4443" --provisioner="kubernetes" \
|
||||||
|
--password-file="$(step path)/password" \
|
||||||
|
--provisioner-password-file="provisioner-password"
|
||||||
|
sudo -E step ca provisioner add acme --type ACME
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure the CA provisioner to issue 90-day certificates:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
sudo jq '(.authority.provisioners[]) += {
|
||||||
|
"claims": {
|
||||||
|
"maxTLSCertDuration": "2160h",
|
||||||
|
"defaultTLSCertDuration": "2160h"
|
||||||
|
}
|
||||||
|
}' /etc/step-ca/config/ca.json > ca-new.json
|
||||||
|
sudo mv ca-new.json /etc/step-ca/config/ca.json
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Put the CA configuration into place, and add the CA to systemd:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
sudo chown -R step:step /etc/step-ca
|
||||||
|
cat <<EOF | sudo tee /etc/systemd/system/step-ca.service
|
||||||
|
[Unit]
|
||||||
|
Description=step-ca service
|
||||||
|
Documentation=https://smallstep.com/docs/step-ca
|
||||||
|
Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
StartLimitIntervalSec=30
|
||||||
|
StartLimitBurst=3
|
||||||
|
ConditionFileNotEmpty=/etc/step-ca/config/ca.json
|
||||||
|
ConditionFileNotEmpty=/etc/step-ca/password
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=step
|
||||||
|
Group=step
|
||||||
|
Environment=STEPPATH=/etc/step-ca
|
||||||
|
WorkingDirectory=/etc/step-ca
|
||||||
|
ExecStart=/usr/local/bin/step-ca config/ca.json --password-file password
|
||||||
|
ExecReload=/bin/kill --signal HUP $MAINPID
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
TimeoutStopSec=30
|
||||||
|
StartLimitInterval=30
|
||||||
|
StartLimitBurst=3
|
||||||
|
|
||||||
|
; Process capabilities & privileges
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
SecureBits=keep-caps
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
|
||||||
|
; Sandboxing
|
||||||
|
ProtectSystem=full
|
||||||
|
ProtectHome=true
|
||||||
|
RestrictNamespaces=true
|
||||||
|
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectClock=true
|
||||||
|
ProtectControlGroups=true
|
||||||
|
ProtectKernelTunables=true
|
||||||
|
ProtectKernelLogs=true
|
||||||
|
ProtectKernelModules=true
|
||||||
|
LockPersonality=true
|
||||||
|
RestrictSUIDSGID=true
|
||||||
|
RemoveIPC=true
|
||||||
|
RestrictRealtime=true
|
||||||
|
PrivateDevices=true
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
MemoryDenyWriteExecute=true
|
||||||
|
ReadWriteDirectories=/etc/step-ca/db
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
cat > ca-csr.json <<EOF
|
Save the root CA certificate:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo cat /etc/step-ca/certs/root_ca.crt | tee ca.pem > /dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, start the CA service:
|
||||||
|
|
||||||
|
```
|
||||||
{
|
{
|
||||||
"CN": "Kubernetes",
|
sudo systemctl daemon-reload
|
||||||
"key": {
|
sudo systemctl enable --now step-ca
|
||||||
"algo": "rsa",
|
|
||||||
"size": 2048
|
|
||||||
},
|
|
||||||
"names": [
|
|
||||||
{
|
|
||||||
"C": "US",
|
|
||||||
"L": "Portland",
|
|
||||||
"O": "Kubernetes",
|
|
||||||
"OU": "CA",
|
|
||||||
"ST": "Oregon"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Results:
|
## Verification
|
||||||
|
|
||||||
|
Check the CA health, then request and save the CA root certificate:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo -u step -E step ca health
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
ok
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now sign out of `controller-0`.
|
||||||
|
|
||||||
|
# Generating certificates
|
||||||
|
|
||||||
|
## Bootstrapping with the CA
|
||||||
|
|
||||||
|
### Bootstrapping your local machine
|
||||||
|
|
||||||
|
Run the following on your local machine.
|
||||||
|
|
||||||
|
Download your CA's root certificate:
|
||||||
|
|
||||||
|
```
|
||||||
|
gcloud compute scp controller-0:ca.pem controller-0:provisioner-password .
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
```
|
```
|
||||||
ca-key.pem
|
|
||||||
ca.pem
|
ca.pem
|
||||||
|
provisioner-password
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Now bootstrap with your CA:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
CA_IP=$(gcloud compute instances describe controller-0 \
|
||||||
|
--format='get(networkInterfaces[0].accessConfigs[0].natIP)')
|
||||||
|
step ca bootstrap --ca-url "https://$CA_IP:4443/" --fingerprint $(step certificate fingerprint ca.pem)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
The root certificate has been saved in /home/carl/.step/authorities/XX.XXX.XXX.XXX/certs/root_ca.crt.
|
||||||
|
The authority configuration has been saved in /home/carl/.step/authorities/XX.XXX.XXX.XXX/config/defaults.json.
|
||||||
|
The profile configuration has been saved in /home/carl/.step/profiles/XX.XXX.XXX.XXX/config/defaults.json.
|
||||||
|
```
|
||||||
|
|
||||||
|
Add your CA URL and fingerprint to the project metadata on GCP, so instances can bootstrap:
|
||||||
|
|
||||||
|
```
|
||||||
|
gcloud compute project-info add-metadata --metadata="STEP_CA_URL=https://10.240.0.10:4443,STEP_CA_FINGERPRINT=$(step certificate fingerprint ca.pem)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
Updated [https://www.googleapis.com/compute/v1/projects/project-id-xxxxxx].
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bootstrapping remote instances
|
||||||
|
|
||||||
|
|
||||||
|
Run each command on every node:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
for i in 0 1 2; do
|
||||||
|
gcloud compute ssh worker-${i} -- \
|
||||||
|
step ca bootstrap \
|
||||||
|
--ca-url "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_URL)" \
|
||||||
|
--fingerprint "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_FINGERPRINT)"
|
||||||
|
gcloud compute ssh worker-${i} -- \
|
||||||
|
step ca bootstrap \
|
||||||
|
--ca-url "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_URL)" \
|
||||||
|
--fingerprint "$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/attributes/STEP_CA_FINGERPRINT)"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
The root certificate has been saved in /home/carl/.step/certs/root_ca.crt.
|
||||||
|
The authority configuration has been saved in /home/carl/.step/config/defaults.json.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Client and Server Certificates
|
## 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.
|
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
|
### The Admin Client Certificate
|
||||||
|
|
||||||
Generate the `admin` client certificate and private key:
|
On your local machine, generate the `admin` client certificate and private key:
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
step ca certificate admin admin.pem admin-key.pem \
|
||||||
cat > admin-csr.json <<EOF
|
--provisioner="kubernetes" \
|
||||||
{
|
--provisioner-password-file="provisioner-password"
|
||||||
"CN": "admin",
|
|
||||||
"key": {
|
|
||||||
"algo": "rsa",
|
|
||||||
"size": 2048
|
|
||||||
},
|
|
||||||
"names": [
|
|
||||||
{
|
|
||||||
"C": "US",
|
|
||||||
"L": "Portland",
|
|
||||||
"O": "system:masters",
|
|
||||||
"OU": "Kubernetes The Hard Way",
|
|
||||||
"ST": "Oregon"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cfssl gencert \
|
|
||||||
-ca=ca.pem \
|
|
||||||
-ca-key=ca-key.pem \
|
|
||||||
-config=ca-config.json \
|
|
||||||
-profile=kubernetes \
|
|
||||||
admin-csr.json | cfssljson -bare admin
|
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -113,24 +293,6 @@ Generate a certificate and private key for each Kubernetes worker node:
|
||||||
|
|
||||||
```
|
```
|
||||||
for instance in worker-0 worker-1 worker-2; do
|
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} \
|
EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
||||||
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
|
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
|
||||||
|
@ -138,13 +300,7 @@ EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
||||||
INTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
INTERNAL_IP=$(gcloud compute instances describe ${instance} \
|
||||||
--format 'value(networkInterfaces[0].networkIP)')
|
--format 'value(networkInterfaces[0].networkIP)')
|
||||||
|
|
||||||
cfssl gencert \
|
step ca certificate "system:node:${instance}" ${instance}.pem ${instance}-key.pem --san "${instance}" --san "${EXTERNAL_IP}" --san "${INTERNAL_IP}" --provisioner "kubernetes" --provisioner-password-file "provisioner-password"
|
||||||
-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
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -159,6 +315,18 @@ worker-2-key.pem
|
||||||
worker-2.pem
|
worker-2.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### The Controller Manager Client Certificate
|
### The Controller Manager Client Certificate
|
||||||
|
|
||||||
Generate the `kube-controller-manager` client certificate and private key:
|
Generate the `kube-controller-manager` client certificate and private key:
|
||||||
|
|
Loading…
Reference in New Issue