1. Clusterrole 만들고 ServiceAccount와 특정 Namespace로 Binding 특정 리소스 타입만 허용
ClusterRole 예제
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
# Role는 metadata: 아래에 namespace: 항목이 있지만 ClusterRole은 모든 namespace에 적용되기 때문에 해당 항목이 없다.
ClusterRoleBinding 예제
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
2. ServiceAccount 만들고 Binding 하기.
- user는 사람을 위한것이지만, 서비스 어카운트는 Pod에서 실행되는 프로세스를 위한 것.
- user는 namespace에 종속적이지 않고 전역을 대상으로 선언되지만, 서비스 어카운트는 namespace에 할당된다.
1) 서비스 어카운트 생성
$ vi pod-reader.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
$ kubectl create -f pod-reader.yaml
$ kubectl get sa
$ kubectl get secret
2) Role 생성
$ vi pod-read-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
$ kubectl create -f pod-read-role.yaml
3) Rolebinding 생성
$ pod-read-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-read-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: pod-reader
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
$ kubectl create -f pod-read-rolebinding.yaml
3. Node Name 세팅하기.
# 일반적인 쿠버네티스 설치 환경에서 Node 이름을 변경하고 싶을 경우. 해당 노드에 SSH 접속 후
$ hostnamectl set-hostname k8s-node01
$ kubeadm rejoin
# 위 명령어를 통해서 node를 다시 추가하게 된다.
4. (마스터노드만) kubernetes 버전 업 하기, uncordon 사용. drain 사용.
- 쿠버네티스 업그레이드는 1단계 씩 진행해야 한다. 1.16 > 1.17 가능, 1.17 > 1.19 불가능)
- cordon을 사용하면 지정된 노드에 더 이상 Pod들이 실행되지 않게 된다.
- uncordon을 사용하면 지정된 노드가 다시 Pod들이 스케줄링 된다.
- drain 은 노드 관리를 위해 지정한 노드에 있는 Pod들을 다른 노드로 이동시키는 명령.
- drain 사용 전에 cordon으로 우선 해당 노드에 더 이상 새로운 Pod들이 실행되지 못하게 한 후 사용한다.
- 이때 Daemonset으로 실행된 Pod들이 있으면 drain에 실패하는데. Daemonset으로 실행 된 Pod 들은 삭제 해도 Daemonset이 다시 실행하기 때문.
- --ignore-daemonsets=true 옵션을 주고 drain 을 실행하면 된다.
ex)
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
MasterNode Ready control-plane,master 27d v1.23.4
WorkerNode1 Ready node 27d v1.23.4
$ kubectl cordon WorkerNode1
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
MasterNode Ready control-plane,master 27d v1.23.4
WorkerNode1 Ready,SchedulingDisabled node 27d v1.23.4
$ kubectl drain WorkerNode1
or
$ kubectl drain WorkerNode1 --ignore-daemonsets=true
# 만약 WorkerNode2가 있다면, Pod들이 전부 WorkerNode2로 넘어가 실행되는것을 확인 할 수 있다.
# WorkerNode1 밖에 없기때문에 Pending 되게 됨.
$ kubectl uncordon WorkerNode01
# 다시 WorkerNode01로 Pod들이 살아나는것 확인.
https://kubernetes.io/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
1) 현재 버전 확인하기.
$ kubectl get node -o wide
or
$ kubeadm version
# 현재 버전 확인
2-1) 마스터노드 버전 업그레이드 방법.
$ apt update
$ apt-cache madison kubeadm
# 목록에서 업그레이드 할 버전을 찾는다.
$ apt-mark unhold kubeadm && \
$ apt-get update && apt-get install -y kubeadm=1.19.0-00 && \
$ apt-mark hold kubeadm
$ kubeadm version
$ kubeadm upgrade plan
$ kubeadm upgrade apply v1.19.00
or
$ apt-get uprade -y kubeadm=1.19.0-00
$ kubeadm upgrade apply v.1.19.0
$ kubeadm version
# 이 상태에서 kubectl get nodes 명령어로 확인하면 마스터 노드 버전이 업그레이드 전 버전으로 보인다.
# 왜냐하면 kubelet의 버전을 보여주기 때문, 따라서 kubelet 버전도 업그레이드 해 줘야 한다. 덤으로 kubectl 도.
$ apt-get upgrade -y kubelet=1.19.0-00
or
$ apt-mark unhold kubelet kubectl
$ apt-get update && apt-get install -y kubelet=1.19.0-00 kubectl=1.19.0.-00
$ apt-mark hold kubelet kubectl
$ systemctl daemon-reload
$ systemctl restart kubelet
# kubelet 재시작 한다.
$ kubectl uncordon master
2-2) 워커노드 버전 업그레이드 방법.
(워커노드에서)
$ apt-mark unhold kubeadm
$ apt-get update && apt-get install -y kubeadm=1.19.0-00
$ apt-mark hold kubeadm
$ kubeadm upgrade node
$ 아직 작성중..
5. ETCD 백업 및 리스토어.
# ETCD 백업.
ETCDCTL_API=3 etcdctl \
--cacert="" --cert="" --key="" \
snapshot save <backup-file-location>
or
ETCDCTL_API=3 etcdctl --cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> snapshot save /opt/etcd-backup.db
$ cd /etc/kubernetes/manifests
$ cat etcd.yaml
# ca.crt / server.crt / server.key 파일들의 경로를 확인하고 다음 명령어를 실행
$ ETCDCTL_API=3 etcdctl --cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> snapshot save /opt/etcd-backup.db
# ETCD 리스토어.
# 리스토어는 백업보다 옵션이 4개가 더 많다.
$ cd /etc/kubernetes/manifests
$ cat etcd.yaml
backup시 필요한 옵션 3가지에
--data-dir=""
--initial-advertise-peer-irls=""
--initial-cluster=""
--name=""
옵션을 더해서 아래 명령어를 실행한다.
ETCDCTL_API=3 etcdctl --cacert="" \
--cert="" \
--key="" \
--data-dir="" \
--initial-advertise-peer-urls="" \
--initial-cluster="" \
--name="" \
snapshot restore
6. Network Policy 생성 후 특정 포트 허용 하되, 특정 NameSpace 에서만 허용 하기.
https://kubernetes.io/ko/docs/concepts/services-networking/network-policies/
Pod가 통신할 수 있는 네트워크 엔티티는 3가지 식별자 조합을 통해 식별 된다.
1) 허용되는 다른 파드 (예외 : 파드는 자신에 대한 접근을 차단할 수 없음)
2) 허용되는 네임스페이스
3) IP 블록(예외 : 파드 또는 노드의 IP 주소와 관계없이 파드가 실행 중인 노드와의 트래픽은 항상 허용)
- 파드 또는 네임스페이스 기반의 네트워크 폴리시를 정의할 때, 셀렉터를 이용하여 셀렉터와 일치하는 파드와 주고 받는 트래픽을 지정한다.
- IP 블록 기반의 네트워크 폴리시를 정의 할 땐, IP 블록(CIDR 범위) 기반으로 정책을 정의한다.
- 기본적으로 파드는 모든 소스에서 오는 트래픽을 받아들인다.
- 네트워크폴리시가 특정 파드를 선택하면 해당 파드는 네트워크 폴리시에서 허용하지 않은 모든 연결을 거부한다.
- 즉 어떤 소스 파드A 와 목적지 파드B의 트래픽을 허용 하려면 파드A의 이그레스 정책과 파드B의 인그레스 정책이 해당 트래픽을 허용해야 한다.
네트워크폴리시 예제
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
위 예시는 다음과 같이 동작 한다.
- 아래 조건 들은 모두 default 네임스페이스에서 role=db 인 모든 Pod들에 적용 된다.
- project=myproject 레이블을 가지는 네임스페이스에 role=frontend 레이블을 가진 Pod 들중 172.17.0.0/16 IP 블록을 가진 Pod들에 대해서 TCP Port 6379 번으로 들어오는 인그레스 트래픽을 허용한다. 그 중에서 172.17.1.0/24 IP 블록을 가진 Pod는 제외 한다.
- 10.0.0.0/24 IP블록을 가진 Pod 로 TCP Port 5978번으로 나가는 이그레스 트래픽을 허용한다.
따라서 위를 참고하여 database 네임스페이스에서 인그레스 트래픽 5432 포트만 허용하는 네트워크폴리시를 만드려면.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-netpol
namespace: database
spec:
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 5432
podSelector: {}
######추가 내용#######
모든 인그레스 트래픽 거부
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
policyTypes:
- Ingress
podSelector: {}
모든 인그레스 트래픽 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
policyTypes:
- Ingress
podSelector: {}
ingress:
- {}
모든 이그레스 트래픽 거부
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
모든 이그레스 트래픽 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- {}
모든 인그레스와 이그레스 트래픽 거부
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
'IT > CKA' 카테고리의 다른 글
[CKA] 1차 시험 불합격.. 기억나는 대로 써보는 문제들. 2 (1) | 2022.03.27 |
---|---|
[CKA] Mock Exam 3 풀이 (0) | 2022.02.28 |
[CKA] Mock Exam 2 풀이 (0) | 2022.02.23 |
[CKA] Mock Exam 1 풀이 (0) | 2022.02.23 |