https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/04-certificate-authority.md


인증서를 생성하도록 하자


인증서는 만들것도 많고, 햇갈릴수 있는 부분이니 꼼꼼히 작업해야한다.



### Certificate Authority 


# ca-config.json 파일 생성

cat > ca-config.json <<EOF

{

  "signing": {

    "default": {

      "expiry": "8760h"

    },

    "profiles": {

      "kubernetes": {

        "usages": ["signing", "key encipherment", "server auth", "client auth"],

        "expiry": "8760h"

      }

    }

  }

}

EOF


# ca-csr.json 파일 생성

cat > ca-csr.json <<EOF

{

  "CN": "Kubernetes",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "US",

      "L": "Portland",

      "O": "Kubernetes",

      "OU": "CA",

      "ST": "Oregon"

    }

  ]

}

EOF


# ca 인증서 생성

cfssl gencert -initca ca-csr.json | cfssljson -bare ca



[root@master01 ~]# ll ca*

-rw-r--r--. 1 root root  232 Nov 23 10:51 ca-config.json

-rw-r--r--. 1 root root 1005 Nov 23 10:51 ca.csr

-rw-r--r--. 1 root root  211 Nov 23 10:51 ca-csr.json

-rw-------. 1 root root 1679 Nov 23 13:26 ca-key.pem

-rw-r--r--. 1 root root 1318 Nov 23 13:26 ca.pem

[root@master01 ~]#


ca-config.json, ca-csr.json (EOF 로 파일 직접생성), ca.csr, ca.pem, ca-key.pem 파일이 있어야 하며, 위의 파일중 ca.pem, ca-key.pem 파일을 사용한다. 


[root@master01 ~]# cat 001_create_ca.sh 

#!/bin/bash


### CA Create


cat > ca-config.json <<EOF

{

  "signing": {

    "default": {

      "expiry": "8760h"

    },

    "profiles": {

      "kubernetes": {

        "usages": ["signing", "key encipherment", "server auth", "client auth"],

        "expiry": "8760h"

      }

    }

  }

}

EOF


cat > ca-csr.json <<EOF

{

  "CN": "Kubernetes",

  "key": {

    "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


이렇게 간단하게 스크립트로 생성하였다. 



### Client and Server Certificates


# admin-csr.json 파일 생성

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


# admin 인증서 생성

cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  admin-csr.json | cfssljson -bare admin


# 결과

# ll admin* | awk {'print $9'}

admin.csr

admin-csr.json

admin-key.pem

admin.pem


admin-csr.json (EOF 로 파일 직접생성), admin.csr, admin.pem, admin-key.pem 파일이 있어야 하며, 위의 파일중 admin.pem, admin-key.pem 파일을 사용한다. 



[root@master01 ~]# cat 002_admin_certificate.sh 

#!/bin/bash


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


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  admin-csr.json | cfssljson -bare admin


이렇게 간단하게 스크립트로 생성하였다. 



### The Kubelet Client Certificates


kubelet 에서 사용할 인증서로, 몇가지 IP(hostname) 정보가 필요하다.

External_IP 는 Master 의 외부노출(haproxy 구성예정) IP 이다. 

INTERNAL_IP 는 Worker Node 의 자기자신 IP 이다. 

instance 는 worker node 의 hostname 정보 이다. 


[root@master01 ~]# cat 003_kubelet_client_certificate.sh 

#!/bin/bash


EXTERNAL_IP=192.168.1.47 

INTERNAL_IP=("192.168.1.57" "192.168.1.58" "192.168.1.60")

instance=("worker01" "worker02" "worker03")


for ((i=0; i<3; i++)); do

cat > ${instance[i]}-csr.json <<EOF

{

  "CN": "system:node:${instance[i]}",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "US",

      "L": "Portland",

      "O": "system:nodes",

      "OU": "Kubernetes The Hard Way",

      "ST": "Oregon"

    }

  ]

}

EOF


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -hostname=${instance[i]},${INTERNAL_IP[i]},${EXTERNAL_IP} \

  -profile=kubernetes \

  ${instance[i]}-csr.json | cfssljson -bare ${instance[i]}

done



위의 내용을 스크립트로 작성하여 sh 003_kubelet_client_certificate.sh 로 수행하였으며, 아래와 같은 인증서가 있어야 한다. 


[root@master01 ~]# ll worker* | awk {'print $9'}

worker01.csr

worker01-csr.json

worker01-key.pem

worker01.pem

worker02.csr

worker02-csr.json

worker02-key.pem

worker02.pem

worker03.csr

worker03-csr.json

worker03-key.pem

worker03.pem



### The Controller Manager Client Certificate

[root@master01 ~]# cat 004_controller-manager-certificate.sh 

#!/bin/bash


cat > kube-controller-manager-csr.json <<EOF

{

  "CN": "system:kube-controller-manager",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "US",

      "L": "Portland",

      "O": "system:kube-controller-manager",

      "OU": "Kubernetes The Hard Way",

      "ST": "Oregon"

    }

  ]

}

EOF


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager


# 스크립트 생성 후 실행

sh 004_controller-manager-certificate.sh 


# 확인

[root@master01 ~]# ll kube-controller* | awk {'print $9'}

kube-controller-manager.csr

kube-controller-manager-csr.json

kube-controller-manager-key.pem

kube-controller-manager.pem


### The Kube Proxy Client Certificate


[root@master01 ~]# cat 005_kube-proxy_client_certificate.sh 

#!/bin/bash


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


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-proxy-csr.json | cfssljson -bare kube-proxy


# 스크립트 생성 후 실행

sh 005_kube-proxy_client_certificate.sh 


# 확인

[root@master01 ~]# ll kube-proxy* | awk {'print $9'}

kube-proxy.csr

kube-proxy-csr.json

kube-proxy-key.pem

kube-proxy.pem



### The Scheduler Client Certificate


[root@master01 ~]# cat 006_kube-scheduler_client_certificate.sh 

#!/bin/bash


cat > kube-scheduler-csr.json <<EOF

{

  "CN": "system:kube-scheduler",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "US",

      "L": "Portland",

      "O": "system:kube-scheduler",

      "OU": "Kubernetes The Hard Way",

      "ST": "Oregon"

    }

  ]

}

EOF


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  kube-scheduler-csr.json | cfssljson -bare kube-scheduler



# 스크립트 생성 후 실행

sh 006_kube-scheduler_client_certificate.sh 


# 확인

[root@master01 ~]# ll kube-scheduler* | awk {'print $9'}

kube-scheduler.csr

kube-scheduler-csr.json

kube-scheduler-key.pem

kube-scheduler.pem



### The Kubernetes API Server Certificate


EXTERNAL_IP 는 master 의 외부노출 IP 이다. (haproxy)

MASTER_IP 는 master node 의 각각의 IP 이다. 


[root@master01 ~]# cat 007_apiserver_certificate.sh 

#!/bin/bash


EXTERNAL_IP=192.168.1.47 

MASTER_IP=192.168.1.21,192.168.1.55,192.168.1.56

KUBERNETES_HOSTNAMES=kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local


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


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -hostname=10.32.0.1,${MASTER_IP},127.0.0.1,${KUBERNETES_HOSTNAMES},${EXTERNAL_IP} \

  -profile=kubernetes \

  kubernetes-csr.json | cfssljson -bare kubernetes



# 스크립트 생성 후 실행

sh apiserver_certificate.sh 

# 확인
[root@master01 ~]# ll kubernetes* | awk {'print $9'}
kubernetes.csr
kubernetes-csr.json
kubernetes-key.pem
kubernetes.pem


### The Service Account Key Pair


[root@master01 ~]# cat 008_service-account_certificate.sh 

#!/bin/bash


cat > service-account-csr.json <<EOF

{

  "CN": "service-accounts",

  "key": {

    "algo": "rsa",

    "size": 2048

  },

  "names": [

    {

      "C": "US",

      "L": "Portland",

      "O": "Kubernetes",

      "OU": "Kubernetes The Hard Way",

      "ST": "Oregon"

    }

  ]

}

EOF


cfssl gencert \

  -ca=ca.pem \

  -ca-key=ca-key.pem \

  -config=ca-config.json \

  -profile=kubernetes \

  service-account-csr.json | cfssljson -bare service-account


# 스크립트 생성 후 실행

sh 008_service-account_certificate.sh 

# 확인
[root@master01 ~]# ll service* | awk {'print $9'}
service-account.csr
service-account-csr.json
service-account-key.pem
service-account.pem


### Distribute the Client and Server Certificates (인증서 배포)


[root@master01 ~]# cat 009_certificate_file_copy.sh 

#!/bin/bash


WORKER=("worker01" "worker02" "worker03")

MASTER=("master01" "master02" "master03")


for ((i=0; i<3; i++)); do

  scp ca.pem ${WORKER[i]}-key.pem ${WORKER[i]}.pem ${WORKER[i]}:~/

  

  sleep 2


done




for ((i=0; i<3; i++)); do

  scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \

    service-account-key.pem service-account.pem ${MASTER[i]}:~/


  sleep 2


done


# 스크립트 생성 후 실행

sh 009_certificate_file_copy.sh 

# 확인
master01, 02, 03 서버의 $home:~/ 에 "ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem service-account-key.pem service-account.pem" 파일이 있어야 한다. 

worker01, 02, 03 서버의 $home:~/ 에 "worker01-key.pem, worker01.pem" 파일이 01, 02, 03 의 이름을 가지고 있어야 한다. 













+ Recent posts