The kubernetes cluster can sign the certificate for TLS communication within the cluster. The ca is the ca of the cluster, and the secret of the serviceaccount in each pod is carried.
1. Create a certificate signing request-csr
$ cat <<EOF | ./cfssl genkey - | ./cfssljson -bare server
{
"hosts": [
"nginx.default.svc.cluster.local"
],
"CN": "nginx.default.svc.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
}
}
EOF
2020/06/03 10:49:59 [INFO] generate received request
2020/06/03 10:49:59 [INFO] received CSR
2020/06/03 10:49:59 [INFO] generating key: ecdsa-256
2020/06/03 10:49:59 [INFO] encoded CSR
Generated the private key file server-key.pem and the signature request file server.csr
2. Create the csr object sent to the Kubernetes API
$ cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: my-svc.default
spec:
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
certificatesigningrequest.certificates.k8s.io/my-svc.default created
View the csr object, the status is Pending
$ k get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
my-svc.default 6m25s kubernetes.io/legacy-unknown kubernetes-admin Pending
3. Approve the certificate signing request
$ k certificate approve my-svc.default
certificatesigningrequest.certificates.k8s.io/my-svc.default approved
$ k get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
my-svc.default 11m kubernetes.io/legacy-unknown kubernetes-admin Approved,Issued
4. Download the certificate file
$ k get csr my-svc.default -o jsonpath='{.status.certificate}' | base64 --decode > server.crt
Obtain the certificate file server.crt
5. Use server.crt and server-key.pem to create https server
5.1 Create a secret for the certificate and private key
k create secret generic https --from-file=server.crt --from-file=server-key.pem
5.2 cm to create nginx configuration file
$ cat <<EOF | k apply -f -
> apiVersion: v1
> kind: ConfigMap
> metadata:
> name: nginx
> data:
> my-nginx-config.conf: |
> server {
> listen 80;
> listen 443 ssl;
> server_name www.example.com;
> ssl_certificate certs/server.pem;
> ssl_certificate_key certs/server-key.pem;
> ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
> ssl_ciphers HIGH:!aNULL:!MD5;
>
> location / {
> root /usr/share/nginx/html;
> index index.html index.htm;
> }
> }
> EOF
configmap/nginx created
5.3 Create nginx deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
initContainers:
- name: page-initiator
image: busybox
imagePullPolicy: Never
command: ['sh', '-c', 'echo $HOSTNAME > /data/index.html']
volumeMounts:
- mountPath: /data
name: page-volume
containers:
- image: nginx:1.7.9
name: nginx
imagePullPolicy: Never
volumeMounts:
- mountPath: /usr/share/nginx
name: page-volume
- mountPath: /etc/nginx/certs
name: certs
readOnly: true
- mountPath: /etc/nginx/conf.d
name: config
readOnly: true
ports:
- containerPort: 80
- containerPort: 443
volumes:
- name: page-volume
emptyDir: {}
- name: certs
secret:
secretName: https
- name: config
configMap:
name: nginx
items:
- key: my-nginx-config.conf
path: https.conf
6. Use ca.crt with serviceaccount in pod to access https site
$ k run curl --image=curlimages/curl --command -- sleep infinity
$ k exec -it curl-9c984d666-9hlfc -- sh
$ curl https://nginx.default.svc.cluster.local --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
nginx-7464848dfc-twmtv