다음은 쿠버네티스 스터디 자료를 참고해 정리한 내용입니다.
<1> 테스트 환경 생성
<2> 인증과 인가 차이
<3> 인증 - kubectl 로 API 서버 사용하기 - X.509 Client 인증으로 해보자.
<4> 인증 방법2 - Auth Proxy 로 사용
<5> 인가 - RBAC (Role Base Access Control)
<6> Service Account 와 API서버 인증 - Bearer token (ServiceAccount token)
<7> Role RoleBinding 를 이용하여 devteam 네임스페이스 내의 파드 조회 가능하게 설정!
<8> ClusterRole ClusterRoleBinding 를 이용하여 모든 네임스페이스 내의 권한 부여
<9> default 서비스 어카운트로 kubernetes 서비스를 통해 API 서버 사용
<10> 파드에 특정 서비스 어카운트 지정 후 kubernetes 서비스를 통해 API 서버 사용
<11> 삭제
<1> 테스트 환경 생성
1
AWS에 구축법
cloudformation으로 K8s 클러스터를 도쿄 리전에 만들어 보자.
https://brunch.co.kr/@topasvga/1681
또는
노트북에 로컬 구축법
https://brunch.co.kr/@topasvga/1682
2
여기서는 AWS에 구축하여 사용하는법으로 설명한다.
ec2 로그인
dig +short ns seo31.cndk.k8s
3
ec2에 role 제공
4
REGION=ap-northeast-1
echo $REGION
aws s3 mb s3://seo-to31 --region $REGION
aws s3 ls
export NAME=seo31.cndk.k8s
export KOPS_STATE_STORE=s3://seo-to31
echo 'export NAME=seo31.cndk.k8s' >>~/.bashrc
echo 'export KOPS_STATE_STORE=s3://seo-to31' >>~/.bash
5
Kops로 로컬도메인으로 클러스터 생성에 20분 소요
kops create cluster --zones="$REGION"a --networking calico --master-size t3.medium --node-size t3.medium --node-count=2 --ssh-public-key ~/.ssh/id_rsa.pub --dns private $NAME -y
6
클러스터 생성되었는지 10분마다 확인
kops validate cluster --wait 10m
7
API 서버에 터미널 2개 로그인하여 확인
scp -i ~/.ssh/id_rsa ~/.kube/config ubuntu@api.seo31.cndk.k8s:/tmp/config
ssh -i ~/.ssh/id_rsa ubuntu@api.seo31.cndk.k8s
모니터링 터미널
watch -d 'kubectl get ns,no,po,svc,deploy,rs,ing,ep -o wide'
8
alias k=kubectl
complete -F __start_kubectl k
k get ns,no,po,svc,deploy,rs,ing,ep
NAME STATUS AGE
namespace/default Active 2d13h
namespace/kube-node-lease Active 2d13h
namespace/kube-public Active 2d13h
namespace/kube-system Active 2d13h
NAME STATUS ROLES AGE VERSION
node/ip-172-20-50-211.ap-northeast-1.compute.internal Ready control-plane,master 2d v1.20.8
node/ip-172-20-62-233.ap-northeast-1.compute.internal Ready node 2d13h v1.20.8
node/ip-172-20-63-189.ap-northeast-1.compute.internal Ready node 2d13h v1.20.8
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 2d13h
NAME ENDPOINTS AGE
endpoints/kubernetes 172.20.50.211:443 2d13h
9
Tool 설지
sudo su -
git clone https://github.com/ahmetb/kubectx /opt/kubectx
ln -s /opt/kubectx/kubens /usr/local/bin/kubens
ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
exit
10
# 네임스페이스 확인
kubens
default
kube-node-lease
kube-public
kube-system
11
# 네임스페이스 변경
cd /home/ubuntu/.kube/
root@ip-172-20-50-211:/home/ubuntu/.kube# chmod 755 config
kubens
default
kube-node-lease
kube-public
kube-system
12
kubectl get pod
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-cc8b58cdf-6hhjc 1/1 Running 0 2d13h
calico-node-5n5r8 1/1 Running 0 2d13h
calico-node-fgnx7 1/1 Running 0 2d13h
calico-node-l24fw 1/1 Running 0 2d13h
coredns-5489b75945-744w6 1/1 Running 0 2d13h
coredns-5489b75945-qlp76 1/1 Running 0 2d13h
13
유틸 설치 - 아마존 리눅스 기반 OS 용
# 디폴트 네임스페이스로 변경법 ? kubens 다음 마이너스 -
kubens -
Context "service-account-context" modified.
Active namespace is "default".
14
# 사용가능한 컨텍스트들 확인과 변경?
kubectx
service-account-context
# 컨텍스트 변경
kubectx <변경할 컨텍스트 명>
<2> 인증과 인가 차이
1
인증 ?
로그인, 인증서 등으로 로그인 하는것
X509 인증 등 = x 파이브 오 나인
kubectl 이 kube config 의 기본 설정파일을 참고해서 사용한다.
2
인가 ?
RBAC (role기반 권한 처리) 등으로 차단 된것 등을 허용하는것
Role Base Access Control
Role과 ClusterRole이 있으며 관리 범위가 틀리다.
Role은?
네임 스페이스 내에서만 동작한다.
Pod ,서비스 Svc 는 네임스페이스 내 소속된다. 권한 관리는 Role로 한다.
Role은 APIGroup, resource, verbs 3개로 구성된다.
Role을 ServiceAccount에 매핑한다. (Role 을 계정에 할당 하는것이다. Role 바인딩)
ClusterRole은 ?
네임스페이스 안에 속하지 않는것은 ClusterRole로 관리한다.
Node, PV , Namespace는 ClusterRole로 관리하다.
여러개 네임스페이스 등 인가도 가능하다.
서비스 아카운트에 클러스터 롤바인딩하는 것이다.
<3> 인증 - kubectl 로 API 서버 사용하기 - X.509 Client 인증으로 해보자.
다음은 KOPS로 구현한 AWS 환경에서 테스트 합니다.
1
kubectl로 API서버 사용 과정 확인
kubectl get node
NAME STATUS ROLES AGE VERSION
ip-172-20-50-211.ap-northeast-1.compute.internal Ready control-plane,master 5m29s .20.8
ip-172-20-62-233.ap-northeast-1.compute.internal Ready node 3m12s v1.20.8
ip-172-20-63-189.ap-northeast-1.compute.internal Ready node 3m58s v1.20.8
2
X.509 Client 인증으로 해보자 ?
상세 디버그 정보 확인 -v7 , v9
kubectl get node -v7
kubectl get node -v9
// 인증 정보가 있는곳.
/root/.kube/config
기본으로 /.kube/config 의 일을 로드 한다.
인증과 인가에 대한 정보가 있다.
AWS API호출이 https 443이다.
GET https://127.0.0.1/api/v1/nodes?limit=500
// API 서버 호출주소
I0725 13:27:22.334825 10473 loader.go:379] Config loaded from file: /home/ubuntu/.kube/config
I0725 13:27:22.346220 10473 round_trippers.go:422] GET https://127.0.0.1/api/v1/nodes?limit=500
I0725 13:27:22.346244 10473 round_trippers.go:429] Request Headers:
:
NAME STATUS ROLES AGE VERSION
ip-172-20-50-211.ap-northeast-1.compute.internal Ready control-plane,master 5m v1.20.8
ip-172-20-62-233.ap-northeast-1.compute.internal Ready node 3m31s v1.20.8
ip-172-20-63-189.ap-northeast-1.compute.internal Ready node 4m17s v1.20.8
3
인증서 정보(파일) 없이 api 서버 접속 테스트 해보자 ?
모두 안된다.
권한이 없으므로
AWS는 포트 없이 도메인 주소가 나온다.
APIADDR=<API접속주소:포트>
APIADDR=127.0.0.1:443
curl -k https://$APIADDR/api/v1/nodes
curl -k https://$APIADDR/apis
curl -k https://$APIADDR/version
curl: (7) Failed to connect to 127.0.0.1 port 443: Connection refused
APIADDR=127.0.0.1:443
curl -k https://$APIADDR/api/v1/nodes
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}ubuntu@ip-172-20-50-211:~$
4
# kubeconfig 인증서 정보(파일) 3가지 확인 ?
CA crt(발급 기관 인증서, certificate-authority-data)
Client crt(클라이언트 인증서, client-certificate-data)
Client key(클라이언트 개인키, client-key-data)
KUBECONFIG=<kubeconfig파일위치>
KUBECONFIG=/home/ubuntu/.kube/config
cat $KUBECONFIG
3가지 내용이 나온다.
clusters:
contexts:
users:
contexts: = clusters: 와 users: 의 조합이다.
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJBZ0lNRnF4YzRlVnAze
server: https://127.0.0.1
name: local
contexts:
- context:
cluster: local
user: kubecfg
name: service-account-context
current-context: service-account-context
kind: Config
users:
- name: kubecfg
user:
client-certificate-data:
client-key-data:
// users: 에는 client-certificate-data: (클라이언트 인증서,Cleint crt) 와 client-key-data: (클라이언트 개인키 Client key , CA Key)가 있다.
6
클라이언트 인증서 = client-certificate-data:
클라이언트 개인키 = client-key-data:
클라이언트 인증서 상세 정보 확인
grep 'client-certificate-data' $KUBECONFIG | head -n 1 | awk '{print $2}' | base64 -d
grep 'client-certificate-data' $KUBECONFIG | head -n 1 | awk '{print $2}' | base64 -d > client.crt
openssl x509 -in client.crt -noout -text
클라이언트 인증서를 파일로 만들어 보자~
grep 'client-certificate-data' $KUBECONFIG | head -n 1 | awk '{print $2}' | base64 -d > client.crt
-----BEGIN CERTIFICATE-----
MIIDITCCAgmgAwIBAgIRAI/QI18pn3wlPuM4tdUjCVwwDQYJKoZIhvcNAQELBQAw
FTETMBEGA1UEAxMKa3ViZXJuZXRlczAeFw0yMTEwMDcxMjM2MDJaFw0yMzAxMjAy
상세 정보 확인
openssl x509 -in client.crt -noout -text
// Subject: O = system:masters, CN = kubecfg // 이미 admin 권한을 가지고 있다!!
$ openssl x509 -in client.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
8f:d0:23:5f:29
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = kubernetes
Validity
Not Before: Oct 7 12:36:02 2021 GMT
Not After : Jan 20 21:36:02 2023 GMT
Subject: O = system:masters, CN = kubecfg // 이미 admin 권한을 가지고 있다!!
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
:
54:17:0e:68:3f:cf:e6:94:71:5d:66:1d:0b:db:2f:8c:21:de:
a9:77:64:ad
8
사용자에 바인딩된 클러스터롤 확인 : Resources(오브젝트) , Verbs(동작) ?
kubectl describe clusterrolebindings cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
// system:masters은 빌트인 클러스터 admin role이다.
9
cluster-admin 클러스터롤 확인 ?
kubectl describe clusterroles cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
// 모든 권한을 가지고 있다.
10
tree 설치?
sudo apt install tree
11
K8S 기본 인증서 파일 확인 ?
tree /etc/kubernetes/
여러가지 인증서와 키가 있다~~
/etc/kubernetes/
├── cloud.config
├── kops-controller
│ ├── ca-key.pem
│ ├── ca.pem
│ ├── kops-controller.crt
│ └── kops-controller.key
├── kube-apiserver-healthcheck
│ └── secrets
│ ├── ca.crt
│ ├── client.crt
│ └── client.key
11
직접 인증서 지정하여 API 사용 ?
클라이언트 인증서,키 파일 추출 하자
해당 파일을 OS인증서 주입 후 웹 브라우저로 API서버 사용 가능!
grep 'client-certificate-data' $KUBECONFIG | head -n 1 | awk '{print $2}' | base64 -d > client.crt
grep 'client-key-data' $KUBECONFIG | head -n 1 | awk '{print $2}' | base64 -d > client.key
인증서와 개인 키를 파일로 만들었다
13
API 서버 사용 테스트 ?
APIADDR=127.0.0.1:443
curl -k --key ./client.key --cert ./client.crt https://$APIADDR/api/v1/nodes
curl -k --key ./client.key --cert ./client.crt https://$APIADDR/apis
curl -k --key ./client.key --cert ./client.crt https://$APIADDR/version
curl -k --key ./client.key --cert ./client.crt https://$APIADDR/
// 잘 된다 ~~
14
인증서 1년 만료기간이 있다.
만료 되기전에 인증서 갱신 해야 한다.
인증서 관리가 중요하다.
kubeadm 툴 설치후 확인
kubeadm certs check-expiration
15
클러스터 인증 관련 설정 정보 확인 ?
kubeadm K8S 환경만 가능
kubectl -n kube-system get cm kubeadm-config -o yaml
16
이제까지 htts로 인증서 값을 가지고 조회하는것을 하였다!
<4> 인증 방법2 - Auth Proxy 로 사용
인증서 정보 없이 Proxy 접속해 kubectl 을 사용해 API Server를 사용해보자
보안에 취약함.
간단하게 API 서버를 사용하고자 할때 사용한다.
1
master node ip 확인?
kubectl get nodes -owide
kubectl get node
NAME STATUS ROLES AGE VERSION
ip-172-20-50-211.ap-northeast-1.compute.internal Ready control-plane,master v1.20.8
ip-172-20-62-233.ap-northeast-1.compute.internal Ready node 22m v1.20.8
ip-172-20-63-189.ap-northeast-1.compute.internal Ready node 23m v1.20.8
dig +short ip-172-20-50-211.ap-northeast-1.compute.internal
172.20.50.211
3
Auth Proxy 실행
AuthPort=<Auth Proxy 사용할 포트 번호>
MasterIP=<마스터 노드 IP>
AuthPort=8000
MasterIP=172.20.32.214
4
(방법1) 터미널이 끊어져도 실행 가능하게 데몬 형태로 실행하기
nohup kubectl proxy --port=$AuthPort --address=$MasterIP --accept-hosts='^*$' >/dev/null 2>&1 &
# 프로세스 멈추기 : ss -tnlp ; kill -9 <pid>
5
(방법2) 터미널1개 띄워놓고 포그라운드에서 실행하기
kubectl proxy --port=$AuthPort --address=$MasterIP --accept-hosts='^*$'
# 프로세스 멈추기 : CTRL+C
6
# API 서버 사용 테스트
curl http://$MasterIP:$AuthPort/api/v1/nodes
curl http://$MasterIP:$AuthPort/apis
curl http://$MasterIP:$AuthPort/
or
자신의 PC 웹브라우저에서 접속 >> AWS EC2(Master Node)일 경우 'Inbound Security Group' 에 '0.0.0.0/0 TCP 8000' 포트 허용 설정 추가 필요
<5> 인가 - RBAC (Role Base Access Control)
인증후 권한을 부여하는것이 인가이다.
1
목적
Service Account 정보 확인하기
2
네임스페이스 생성 한다.
기본적으로 자동으로 생기는 서비스 어카운트(SA)가 생성됨
서비스 어카운트가 가지는 디폴트 권한이 생긴다.
3
서비스어카운트 sa 확인
kubectl get sa
or
kubectl get serviceaccounts
NAME SECRETS AGE
default 1 2d13h
2
kubectl describe sa default
Name: default
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-zkk9j
Tokens: default-token-zkk9j
Events: <none>
3
kubectl get secrets
NAME TYPE DATA AGE
default-token-zkk9j kubernetes.io/service-account-token 3 2d13h
4
kubectl describe secrets
NAME TYPE DATA AGE
default-token-zkk9j kubernetes.io/service-account-token 3 2d13h
ubuntu@ip-172-20-50-211:~$ kubectl describe secrets
Name: default-token-zkk9j
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 7e8ba908-bbcd-4eb5-9adc-1a9706467c03
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1082 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIzVycGJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZ
// 토
5
kubectl describe secrets default-token-zkk9j
6
# 네임스페이스(NS) 신규 생성과 정보 확인
툴 설치
git clone https://github.com/ahmetb/kubectx /opt/kubectx
ln -s /opt/kubectx/kubens /usr/local/bin/kubens
ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
7
kubens
default
devteam
kube-node-lease
kube-public
kube-system
8
chmod 755 config 해야 한다.
9
kubectl create ns devteam
kubens devteam
Context "service-account-context" modified.
Active namespace is "devteam".
kubectl describe sa
Name: default
Namespace: devteam
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-gtl6g
Tokens: default-token-gtl6g
Events: <none>
kubectl describe secrets
Name: default-token-gtl6g
Namespace: devteam
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: b978c213-cded-45a4-9674-b31e2a9b113e
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1082 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ind
7
watch -d 'kubectl get ns,no,po,svc,deploy,rs,ing,ep -o wide'
NAME STATUS AGE
namespace/default Active 2d14h
namespace/devteam Active 56m
namespace/kube-node-lease Active 2d14h
namespace/kube-public Active 2d14h
namespace/kube-system Active 2d14h
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node/ip-172-20-50-211.ap-northeast-1.compute.internal Ready control-plane,master 2d14h v1.20.8 172.20.50.211 18.179.205.221 Ubuntu 20.04.2 LTS 5.4.0-1047-aws containerd://1.4.4
ssh -i ~/.ssh/id_rsa ubuntu@api.seo31.cndk.k8s
alias k=kubectl
complete -F __start_kubectl k
k get ns,no,po,svc,deploy,rs,ing,ep
8
devteam NS에 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
app: pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
9
k get pods
<6> Service Account 와 API서버 인증 - Bearer token (ServiceAccount token)
1
NS 생성 시 자동 생성되는 SA(서비스 어카운트)의 토큰(token) 정보 추출
kubens devteam
//kube ns는 네임스페이스를 변경하는 유틸
kubectl get secrets $(kubectl get sa -o jsonpath="{.items[0].secrets[0].name}") -o jsonpath="{.data.token}" | base64 -d
출력값이 나옴
// 출력값을 token 이라는 변수에 입력
TOKEN=`kubectl get secrets $(kubectl get sa -o jsonpath="{.items[0].secrets[0].name}") -o jsonpath="{.data.token}" | base64 -d`
echo $TOKEN
2
kubectl get node -v7
I0728 04:08:34.190463 2597686 loader.go:379] Config loaded from file: /home/ubuntu/.kube/config
I0728 04:08:34.198210 2597686 round_trippers.go:422] GET https://127.0.0.1/api/v1/nodes?limit=500
I0728 04:08:34.198231 2597686 round_trippers.go:429] Request Headers:
I0728 04:08:34.198241 2597686 round_trippers.go:433] Accept:
3
# Bearer token (ServiceAccount token) 인증을 통한 API서버 접속
APIADDR=<API접속주소:포트>
APIADDR=127.0.0.1:443
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:serviceaccount:devteam:default\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
잘됨 3가지
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/apis
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/version
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1
안됨
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/pods/
3
NS 생성 시 자동 생성되는 default SA는 일부 권한이 바인딩되어 있어서 기본 pod 정보 확인은 실패!
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/pods/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "pods is forbidden: User \"system:serviceaccount:devteam:default\" cannot list resource \"pods\" in API group \"\" in the namespace \"devteam\"",
"reason": "Forbidden",
"details": {
"kind": "pods"
},
"code": 403
<7> Role RoleBinding 를 이용하여 devteam 네임스페이스 내의 파드 조회 가능하게 설정!
1
Role 생성하고 RoleBinding하자.
Role 형식?
네임 스페이스가 존재한다.
rules가 있다.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: service-reader
rules:
- apiGroups: [""] # 1. 대상이 될 오브젝트의 API 그룹
resources: ["services"] # 2. 대상이 될 오브젝트의 이름. 현재 디폴트 값
verbs: ["get", "list"] # 3. 어떠한 동작을 허용할 것인지 명시
2
# API Resource 정보 확인
kubectl api-resources | head -1 ; kubectl api-resources | grep rbac
NAME SHORTNAMES APIVERSION NAMESPACED KIND
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
// clusterrolebindings , clusterroles 은 네임스페이스 밖에 존재.
//rolebindings, roles은 네임스페이스 안에 존재.
3
kubectl api-resources -owide
각각의 object에서 할수 있는 부분이 나온다.
create , delete 등이 사용 할수 있는 옵션을 보여준다.
4
role을 생성해 pod 조회 권한을 부여해보자 ?
# devteam NS 에 Role 생성
kubens devteam
Context "service-account-context" modified.
Active namespace is "devteam".
5
role 만들자.
종류 role
role 은 namespace가 있다. namespace안에서 존재하니까
클러스터 role은 네임스페이스가 없다. namespace 밖에 있으니까
rules = 권한이 있다.
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-role1
namespace: devteam
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
EOF
// pods 가 core api 그룹으로 "" 안쓴다.
4
# Role 확인(NS 내 적용 동작)
kubectl get roles
NAME CREATED AT
dev-role1 2021-07-28T04:14:42Z
5
kubectl describe roles dev-role1
Name: dev-role1
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list]
// pod에 대해 get과 list를 할수 있다.
6
# RoleBinding 생성 ?
default 서비스 어카운트와 Role 바인딩 한다.
계정과 role 을 연결
종류 RoleBinding
namespace 있다.
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-rolebind1
namespace: devteam
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dev-role1
subjects:
- kind: ServiceAccount
name: default
namespace: devteam
EOF
// role과 서비스 어카운트를 바인딩 한다.
7
확인
kubectl get rolebindings
NAME ROLE AGE
dev-rolebind1 Role/dev-role1 37s
8
kubectl describe rolebindings dev-rolebind1
Name: dev-rolebind1
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: dev-role1
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount default devteam
// role과 서비스 어카운트가 연결 되어 있다.
9
# 확인을 위해서 서비스 생성 ?
kubens devteam
Context "service-account-context" modified.
Active namespace is "devteam".
10
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
selector:
app: pod
ports:
- port: 8080
targetPort: 80
EOF
11
# 확인
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-1 ClusterIP 100.67.127.140 <none> 8080/TCP 17s
12
kubectl get ep
NAME ENDPOINTS AGE
svc-1 100.98.83.1:80 45s
13
kubectl get all,ep
NAME READY STATUS RESTARTS AGE
pod/pod-1 1/1 Running 0 42m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/svc-1 ClusterIP 100.67.127.140 <none> 8080/TCP 56s
NAME ENDPOINTS AGE
endpoints/svc-1 100.98.83.1:80 56s
14
# Bearer token (ServiceAccount token) 인증을 통한 API서버 접속 - Role Rolebinding 설정된 상태!
APIADDR=<API접속주소:포트>
APIADDR=127.0.0.1:443
# 아래 조회 중 되는것 안되는것 이 있다! 왜그럴까?
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/pods/
잘 됨!
서비스 조회는 안됨.
권한이 없어서.
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/services/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services is forbidden: User \"system:serviceaccount:devteam:default\" cannot list resource \"services\" in API group \"\" in the namespace \"devteam\"",
"reason": "Forbidden",
"details": {
"kind": "services"
},
"code": 403
15
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/nodes
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/
<8> ClusterRole ClusterRoleBinding 를 이용하여 모든 네임스페이스 내의 권한 부여
네임스페이스를 별도로 만든다.
별도의 서비스 어카운트를 만든다.
다른 네임스페이스에 있는 dev 네임스페이스를 조회 한다. dev에 있는것 pod,svc 조회해 보자.
클러스터 Role은 모든 네임스페이스 안에 있는 오브젝트를 사용할수 있는 권한 제공 가능.
클러스터 Role은 네임스페이스 에 있는 오브젝트를 사용할수 있는 권한 제공 가능.
1
# 인프라 네임스페이스(NS) 신규 생성 및 정보 확인 하자
kubectl create ns infrateam
namespace/infrateam created
2
kubens infrateam
Context "service-account-context" modified.
Active namespace is "infrateam".
3
kubectl describe sa && kubectl describe secrets
Name: default
Namespace: infrateam
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-jsz4c
Tokens: default-token-jsz4c
Events: <none>
Name: default-token-jsz4c
Namespace: infrateam
Labels: <none>
Annotations: kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 98bc5e94-13a6-4647-9c72-d2df875fefb4
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1082 bytes
namespace: 9 bytes
token: eyJhbGciOiJSUzI1
4
# 서비스 어카운트 생성 - infrateam 네임스페이스에 소속됨
본인 이름으로 서비스 어카운트를 만들어 테스트 하자.
NICK=<편한 닉네임, 소문자로>
NICK=masterseo
kubectl create sa $NICK
serviceaccount/masterseo created
5
# 확인
kubectl get sa
NAME SECRETS AGE
default 1 92s
masterseo 1 17s
6
토큰이 있다~
디폴트 권한만 있다.
kubectl get secrets
NAME TYPE DATA AGE
default-token-jsz4c kubernetes.io/service-account-token 3 108s
masterseo-token-dwpn4 kubernetes.io/service-account-token 3 33s
7
# 클러스터롤과 롤바인딩 생성 ?
모든 리소스에 모든 권한을 가진 role 을 만든다 !!
- apiGroups: ["*"]
verbs: ["*"]
resources: ["*"]
바인딩하고, nick name에 권한까지 준다.
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-role-01
rules:
- apiGroups: ["*"]
verbs: ["*"]
resources: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-rolebind-01
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-role-01
subjects:
- kind: ServiceAccount
name: $NICK
namespace: infrateam
EOF
clusterrole.rbac.authorization.k8s.io/cluster-role-01 created
clusterrolebinding.rbac.authorization.k8s.io/cluster-rolebind-01 created
8
kubectl describe clusterroles cluster-role-01
Name: cluster-role-01
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
9
kubectl get clusterrolebindings cluster-rolebind-01
NAME ROLE AGE
cluster-rolebind-01 ClusterRole/cluster-role-01 81s
10
kubectl describe clusterrolebindings cluster-rolebind-01
Name: cluster-rolebind-01
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: cluster-role-01
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount masterseo infrateam
12
# <닉네임> SA(서비스 어카운트)의 토큰(token) 정보 추출
TOKEN=`kubectl get secrets $(kubectl get sa $NICK -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 -d`
echo $TOKEN
eyJhbGciOiJSUzI1NiIsImtpZCI6IndXdlJocVFkREhyZHQzck9UNEx0MktwTFlqOTJScURVZC1mQzVy
13
# 다른 네임스페이스 오브젝트에 대해서 API서버 조회 ?
Bearer token (ServiceAccount token)
dev팀의 pod가 조회 가능하다~
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/pods/
다른 네임스페이스의 Pod 조회가 가능하다 !!
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "544437"
},
"items": [
{
"metadata": {
"name": "pod-1",
"namespace": "devteam",
"uid": "cc279997-35b2-47cd-8cb3-03abe10f55e8",
"resourceVersion": "537118",
"creationTimestamp": "2021-07-28T03:38:01Z",
"labels": {
"app": "pod"
},
14
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/namespaces/devteam/services/
노드의 정보도 조회 된다. = 클러스터 레벨의 권한이 있다.
curl -k -H "Authorization: Bearer $TOKEN" https://$APIADDR/api/v1/nodes
<9> default 서비스 어카운트로 kubernetes 서비스를 통해 API 서버 사용
1
# devteam NS 로 변경
kubens devteam
Context "service-account-context" modified.
Active namespace is "devteam".
2
# 이전 실습에서 생성해둔 pod-1 의 Mounts 와 ConfigMap 정보 확인
kubectl describe pod pod-1 | egrep '(Mounts|ConfigMapName)' -A1
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-gtl6g (ro)
3
kubectl get configmaps -o yaml
apiVersion: v1
items:
- apiVersion: v1
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIC8jCCAdqgAwIBAgIMFpULGp3W2XRcR+LMMA0GCSqGSIb3DQEBCwUAMBUxEzAR
4
(옵션) 파드(pod-1) 생성된 노드에서 컨테이너 상세 정보 확인
clear
docker inspect ec6c4d010772 | grep Mounts -A8
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/2b9f016c-b43a-4f1c-83d4-bc2ca276af1d/volumes/kubernetes.io~projected/kube-api-access-xc7vf",
"Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
},
...
5
# 파드에 기본 적용되는 서비스 어카운트(토큰)
kubectl exec -it pod-1 -- ls /run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
kubectl exec -it pod-1 -- cat /run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IndXdlJocVFkREhyZHQzck9UNEx0MktwTFlqOTJScURVZC1mQzVycGxzR28ifQ.eyJp
kubectl exec -it pod-1 -- cat /run/secrets/kubernetes.io/serviceaccount/namespace
devteam
kubectl exec -it pod-1 -- cat /run/secrets/kubernetes.io/serviceaccount/ca.crt
-----BEGIN CERTIFICATE-----
MIIC8jCCAdqgAwIBAgIMFpULGp3W2XRcR+LMMA0GCSqGSIb3DQEBCwUAMBUxEzAR
BgNVBAMTCmt1YmVybmV0ZXMwHhcNMjEwNzIzMTMxNzMwWhcNMzEwNzIzMTMxNzMw
6
# API서버 정보 확인
kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 2d15h
devteam svc-1 ClusterIP 100.67.127.140 <none> 8080/TCP 17m
kube-system kube-dns ClusterIP 100.64.0.10 <none> 53/UDP,53/TCP,9153/TCP
7
kubectl describe svc kubernetes -n default
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP Families: <none>
IP: 100.64.0.1
IPs: 100.64.0.1
Port: https 443/TCP
TargetPort: 443/TCP
Endpoints: 172.20.50.211:443
Session Affinity: None
Events: <none>
8
# 파드 Shell 실행
kubectl exec -it pod-1 -- zsh
Welcome to Netshoot! (github.com/nicolaka/netshoot)
9
# API 서버 DNS 쿼리 정보 확인
# 아래 쿼리 중 어떤건 안되는 것이 있다. 왜그럴까?
cat /etc/resolv.conf
nslookup kubernetes
nslookup kubernetes.default
nslookup kubernetes.default.
nslookup kubernetes.default.svc
nslookup kubernetes.default.svc.
nslookup kubernetes.default.svc.cluster.local
nslookup -type=A kubernetes -debug | grep QUESTIONS -A1
nslookup -type=A kubernetes.default -debug | grep QUESTIONS -A1
# API 서버 접근 - 여기도 확인 !
curl https://kubernetes -k
curl https://kubernetes.default -k
10
# 파드 내에서 어떻게든 API 서버 접근을 해보자!
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $TOKEN
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/version
eyJhbGciOiJSUzI1NiIsImtpZCI6IndXdlJocVFkREhyZHQzck9UNEx0MktwTFlqOTJScURVZC1mQzVycy5pb
{
"major": "1",
"minor": "20",
"gitVersion": "v1.20.8",
"gitCommit": "5575935422cc1cf5169dfc8847cb587aa47bac5a",
"gitTreeState": "clean",
"buildDate": "2021-06-16T12:53:07Z",
"goVersion": "go1.15.13",
"compiler": "gc",
"platform": "linux/amd64"
}#
11
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/apis
{
"kind": "APIGroupList",
"apiVersion": "v1",
"groups": [
{
"name": "apiregistration.k8s.io",
"versions": [
{
"groupVersion": "apiregistration.k8s.io/v1",
"version": "v1"
},
{
"groupVersion": "apiregistration.k8s.io/v1beta1",
"version": "v1beta1"
}
],
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/api/v1/nodes
exit
12
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/api/v1/nodes
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "nodes is forbidden: User \"system:serviceaccount:devteam:default\" cannot list resource \"nodes\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "nodes"
},
"code": 403
}
#
<10> 파드에 특정 서비스 어카운트 지정 후 kubernetes 서비스를 통해 API 서버 사용
1
# infrateam NS 로 변경
kubens infrateam
1
# 이전 실습에서 생성한 서비스 어카운트 정보 확인
kubectl get sa ; kubectl get secret ; kubectl describe clusterrolebindings cluster-rolebind-01
3
# 닉네임 변수 지정(혹은 확인)
NICK=<닉네임>
NICK=masterseo
4
# 파드 생성 시 특정 서비스 어카운트의 시크릿을 마운트 하기
# infrateam NS에 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
app: pod
spec:
serviceAccountName: $NICK
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
// serviceAccountName: $NICK
Pod 생성할때 서비스 어카운트 매핑이 가능하다.
5
# 파드 Shell 실행
kubectl exec -it pod-1 -- zsh
-----------------------------
# API 서버 접속 확인
nslookup kubernetes.default
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $TOKEN
몇가지 조회가 된다.
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/api/v1/nodes
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/api/v1/namespaces/devteam/pods/
curl --header "Authorization: Bearer $TOKEN" -k https://kubernetes.default/api/v1/namespaces/devteam/services/
curl https://kubernetes.default/ -k
exit
<11> 삭제
1
kubens default
Context "service-account-context" modified.
Active namespace is "default".
2
kubectl delete ns devteam infrateam
namespace "devteam" deleted
namespace "infrateam" deleted
3
clusterrolebindings ?
kubectl delete clusterrolebindings cluster-rolebind-01 && kubectl delete clusterroles cluster-role-01
clusterrolebinding.rbac.authorization.k8s.io "cluster-rolebind-01" deleted
clusterrole.rbac.authorization.k8s.io "cluster-role-01" deleted
다음 보기
https://brunch.co.kr/@topasvga/1745
https://brunch.co.kr/@topasvga/1656
감사합니다.