본문 바로가기

kubernetes, helm, rancher

kubernetes auth, certificates

기본적인 kubernetes resource, option 등을 설명한 블로그입니다. 추가적인 기능을 보고싶으시면 docs를 참고바랍니다.

https://kubernetes.io/docs/home/

 

Kubernetes Documentation

Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation.

kubernetes.io

  • 인증을 하는 방식은 여러가지가 있는데 static password file, static token file, ceertificates, third party가 있다.
  • file을 이용하는 방식은 file안에 정보를 입력하고(ex: csv) ExecStart=kube-apiserver --basic-auth-file=[filename]을 전달해주거나, kube-apiserver pod내의 command에 --basic-auth-file=[filename]을 넣어준다. (token일 경우 --token-auth-file=[token file])
  • 하지만 위의 방식들은 너무 insecure해서 1.19버전부터 deprecate됬다.
  • certificates는 kube-apiserver.crt, kube-apiserver.key, etcd.crt, etcd.key, kubelet.key, kubelet.crt 등등 component별로 있다.
  • kubectl config view를 통해 본 contexts의 user가 리눅스의 root처럼 다른 리소스에 대한 쿠버네티스의 user. -> ~/.kube/config안에 인증서 정보가 있어서 그걸 이용해서 kubectl을 통한 api요청 가능.
  • Human User 또는 group -> 클러스터 외부에서 쿠버네티스를 조작하는 사용자. (ex 인증서)
  • account는 user account, service account 두가지가 있으며, serviceaccount는 kubernetes cluster와 상호작용하는 application이다.
  • serviceaccount -> 쿠버네티스 내부적으로 관리되며, pod가 쿠버네티스 api를 다룰 때 사용하는 계정. 
  • serviceaccount를 생성하면 token이 발급되고, secret에 저장된다. kubectl describe secrete [token name]
  • 이러한 secret은 kubectl exec -it [pod name] -- ls /var/run/secrets/kubernetes.io/serviceaccount로 확인 가능.
  • kubernetes-admin은 모든 api 권한을 가지므로 user를 생성할 때 제한된 권한을 부여한다.
  • pod나 deployment등 resource가 생성될 때 serviceaccount는 default지만 deployments pod tamplate에서 serviceAccountName: [name]을 통해 지정해줄 수 있고, mount를 자동으로 하기 싫을 때에는 automountServiceAccountToken: false로 주면되며, 이러한 항목들은 countainers와 indent가 같다.
  • 모든 component(user, kubelet, kube-apiserver, etcd 등)는 각각의 crt, key를 가지고 있다.
  • kube-apiserver 같은 경우, crt, key를 가지고 있지만, etcd, kubelet과 통신하는 유일한 component이기 때문에, 오직 etcd, kubelet과 통신하기 위한 crt, key를 가지고 있다. 예를 들어 apiserver.crt 뿐만 아니라, apiserver-etcd-client.crt를 가지고 있다.

 

# server self-signed 인증서 생성
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=server"
openssl x509 -req -in server.csr -signkey server.key -out server.crt

# server signed 인증서 user용 생성
openssl genrsa -out admin.key 2048
openssl req -new -key admin.key -out admin.csr -subj "/CN=admin"
openssl x509 -req -in admin.csr -CA server.crt -CAkey server.key -out admin.crt

# 만약 다른 user와 구분짓고 싶다면 /O로 group을 명시해준다.
openssl req -new -key admin.key -out admin.csr -subj "/CN=admin/O=system:masters"
  • self-signed로 하기 싫고 ca를 통해 인증받고 싶다면, /etc/kubernetes/pki 폴더안에 ca.crt, ca.key가 있으니 그걸로 인증받으면 된다.
  • 위에서 /CN의 값은 무조건 user의 이름과 같아야 한다. 아니면 권한 에러남.
  • 이제 user, password 대신 certificates로 인증가능
  • 중요한 점은, 아직 role이 없으니까 role과 rolebinding을 만들어서 실행해줘야 권한이 생긴다.
  • curl https://[kube-apiserver]:6443/api/v1/pods --key admin.key --cert admin.crt --cacert server.crt
  • 해당 user가 특정 namespace만을 권한을 가질 때 https://[kube-apiserver]:6443/api/v1/namespaces/[namespace]/pods 이렇게 작성하면 된다.
  • kubectl get pods --server [kube-apiserver]:6443 --client-key admin.key --client-certificate admin.crt --certificate-authority server.crt
  • 하지만 위의 명령어는 너무 기니까 kubeconfig file에 위의 파라미터를 넣어서 kubectl get pods --kubeconfig [configfile] 해주거나 $HOME/.kube/config 파일에 추가해주면 kubectl get pods만 해도 된다.
  • $HOME/.kube/config 파일에 추가하는 방법은 파일에 vi에디터를 이용할 수 있지만, 아래와 같이 명령어를 사용할 수 있다.
kubectl config set-credentials $USERNAME \
  --client-certificate=$(pwd)/$CRT_FILE \
  --client-key=$(pwd)/$KEY_FILE

kubectl config set-context $USERNAME-context --cluster=$CLUSTERNAME \
--namespace=$NAMESPACE --user=$USERNAME
  • https://[kube-apiserver]에서 kube-apiserver는 해당 server ip를 의미한다.
  • user가 cluster에 접근하고 싶어서 csr을 보내 인증된 crt를 받기위해 master node에 접근하는 방식이 user가 많아지면 manural하게 하기가 힘들기 때문에 certificate api가 있다.

 

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: [인증서 요청 정보(csr), cat file.csr | base64 정보를 넣는다.]
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400 # one day
  groups:
  - system:authenticated
  usages:
  - client auth

 

 

# 인증서 요청 정보(csr)
cat myuser.csr | base64 | tr -d "\n"
# csr 인증서 요청서를 base64로 인코딩한 다음 줄바꿈 없애서 한줄로.

 

  • kubectl apply -f 하고 kubectl get csr로 정보를 보면 pending 상태임을 확인 할 수 있다.
  • pending상태는 승인이 안났으므로, kubectl cerificate approve [csr name]를 통해 승인을 해주어야 한다.
  • deny하고 싶다면 kubectl certificate deny [csr name] 해주면 된다.

 

# 인증서 얻기
kubectl get csr [csr name] -o jsonpath='{.status.cerificate}' | bash64 -d > myuser.crt
  • 위의 과정들은 kube-api server가 certificate을 approve하는 clusterrole과 바인딩 되어 관리해준다.

  • cat /etc/kubernetes/manifests/kube-controller-manager.yaml을 보면 ca.crt, ca.key가 있다.
  • kubelet configuration을 통해 crt 이름 지정.
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  x509:
    clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
  mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
  - "10.32.0.10"
podCIDR: "${POD_CIDR}"
resolvConf: "/run/systemd/resolve/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/kubelet-node01.crt"
tlsPrivateKeyFile: "/var/lib/kubelet/kubelet-node01.key"
# 보통 node 이름을 cert에 넣어준다.
# server라면 위처럼 넣어주고, client라면 system:node:node01같이 넣어줘 구분짓게 한다.
  • openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout으로 certificate 정보를 볼 수 있다.
  • logging system인 journalctl -u etcd.service -l or kubectl logs etcd-master, docker logs을 통해 log에 certficate를 embed한 것을 볼 수 있다.

 

 

'kubernetes, helm, rancher' 카테고리의 다른 글

kubernetes Auto Scaling, metric server  (0) 2021.12.08
kubernetes Volumes, pv, pvc, Storage class  (0) 2021.12.03
kubernetes scheduling  (0) 2021.12.01
kubernetes configmap, secret  (0) 2021.11.30
kubernetes labels  (0) 2021.11.28