CKA #7 Security
정말 길다고 느꼈고, 안써본 리소스들이 많아서 공부하는데 꽤 시간이 걸렸던 것 같습니다. 안써봤었던 컴포넌트들이 많아 나중에 다시 복습도 해봐야 할 것 같습니다.
Index
- CKA #2 Core Concepts, #3 Scheduling
- CKA #4 Logging & Monitoring, #5 Application LifeCycle Management
- CKA #6 Cluster Maintenance
- CKA #7 Security
- CKA #8 Storage
- CKA #9 Networking
Security Primitives
- Password base authentication Disabled
SSH Key based authentication
- kube-apiserver는 쿠버네티스 클러스터의 중심이다. 거의 모든 작업을 수행할 수 있다. 즉, kube-apiserver는 보안의 최전선에 있다.
- 누가 클러스터에 접근할 수 있고, 무엇을 할 수 있는가가 중요한 포인트
- kube-apiserver 외의 컴포넌트들은 TLS로 보안 처리
- 이론적으로 모든 파드는 다른 파드에 접근할 수 있다. 네트워크 정책을 이용해 엑세스 권한을 제어해야 한다.
누가 접근할 수 있는가? → Authentication
API 서버에 인증할 수 있는 다양한 방법이 존재함
- Files - Username & PW
- Files - Username & Token
- Certificates
- External Authentication providers - LDAP
- Service Accounts
무엇을 할 수 있는가? → Authorization
- RBAC Authorization
- ABAC Authorization
- Node Authorization
- Webhook Mode
Authentication - 클러스터 관리에 대한 엑세스 보안
- 클러스터에 엑세스할 수 있는 다양한 사용자가 있다.
엔드 유저는 어플리케이션이 보안을 관리하니 논외로 하고, Admin과 Developer, 그리고 Bots(Application 등)이 남았다.
쿠버네티스는 사용자 계정을 직접 관리하지 않는다. 외부 소스에 의존한다. 사용자 파일, 인증서, LDAP 등. 쿠버네티스 클러스테에서 사용자를 생성하고 관리할 수 없다. 하지만 ServiceAccount는 만들고 관리할 수 있다.
모든 사용자 엑세스는 kube-apiserver에 의해 관리된다. kubectl과 curl 등의 API 요청을 포함한다. kube-apiserver는 요청을 처리하기 전에 사용자 인증을 먼저 한다.
kube-apiserver는 여러 방법의 인증 메커니즘을 지우너한다. 고정 암호 파일, 스태틱 토큰 파일, 인증서, LDAP 등.
여기서는 가장 이해하기 쉬운 Static PW File과 Static Token File을 다룬다.
사용자 이름, 암호, 토큰을 명확히 파일에 저장하는 이 인증 메커니즘은 불안정해 실제에서는 권장하지 않는다.
이 시도를 해보고 싶다면, auth 파일을 저장해둘 volumeMount도 고려하여야 한다.
Static PW File
- CSV 파일에 사용자 목록과 암호를 만들 수 있다.
# user-details.csv
password123,user1,u0001,group1
password123,user2,u0002,group2
password123,user3,u0003,group2
...
- kube-apiserver의 옵션으로 해당 파일을 넘겨준다.
--basic-auth-file=user-details.csv
# kube-apiserver.service
ExecStart=/usr/local/bin/kuve-apiserver \\
--advertise-address=...
...
# 여기 추가한다.
- 그리고 kube-apiserver를 재시작해준다.
- 만약 파드로 kube-apiserver가 관리되고있다면,
/etc/kubernetes/manifests/kube-apiserver.yaml
의spec.containers.command
에 옵션을 추가해준다. - 유저는 다음과 같은 형태로 유저 로그인 정보를 넘겨 인증받는다.
curl -v -k https://masternodeip:6443/api/v1/pods -u "user1:password123"
Static Token File
# user-token-details.csv
tke12139cYaa317,user1,u0001,group1
rJdasrRtj213fjd,user2,u0002,group2
AxS9xDks96Fsgos,user3,u0003,group2
--token-auth-file=user-token-details.csv
curl -v -k https://masternodeip:6443/api/v1/pods --header "Authorization: Bearer tke12139cYaa317"
TLS Certificates
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
CA Certificate
- Generate Keys:
- ca.key
openssl genrsa -out ca.key 2048
- Certificat Signing Request
openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr
- 인증서 서명 요청은 앞서 만든 인증서에 서명을 만드는 과정이다.
- Sign Certificates
openssl x509 -req -in ca.csr -signkey ca.k
- x509는 서명하는 명령어다.
- 사실 자체 서명한 것임. 다른 모든 인증서에는 CA키 인증페어를 이용해 서명할 것임
Client Certificate
- Generate Keys:
- admin.key
openssl genrsa -out admin.key 2048
- Certificate Signing Request
openssl req -new -key admin.key -subj "/CN=kube-admin/O=system:masters" -out admin.csr
- Sign Certificates
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt
kube-apiserver에 엑세스하는 다른 구성 요소에 대한 클라이언트 인증서를 생성하는 프로세스는 모두 같다.
kube-config.yaml 파일에 인증서 정보를 담는 방법과, curl 요청을 날릴 때 옵션으로 key 파일을 지정해주는 방법이 있다. 보통 kube-config 쓴다.
issuer 정보 찾기
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
cert, key 파일 등은 어디있는가?
/etc/kubernetes
경로 안에 있다.
대부분의 컨트롤플레인 구성 요소들은 어디있을까
/etc/kubernetes/manifests
안에 definition 파일들이 존재한다.
CA 서버란?
CA는 키와 인증서 파일 페어다. 이 파일 쌍에 접근할 수 있는 사람은 누구든 쿠버네티스 환경에 대한 인증서에 서명할 수 있다. CA 파일이 있으면 원하는만큼 많은 사용자를 만들 수 있다. 그래서 안전하게 보관해야 한다. → CA 서버라고 부른다. CA 서버에만 CA가 보관된다. 인증서에 서명할 때마다 해당 서버에 로그인하게 만들 수 있다.
쿠버네티스의 마스터 노드는 CA 서버이기도 하다. kubeadm 도구도 마찬가지다. CA 페어를 만들어 마스터 노드에 저장한다. 서명을 수동으로 하기에는 한계가 이기에 자동화가 필요하다. 따라서 쿠버네티스엔 내장 인증서 API를 지원해 자동화시킬 수 있다. 서명 요청을 API 콜로 보낼 수 있다.
- Create CertificateSigningRequest Object → 서명 요청은 클러스터 관리자들이 볼 수 있다.
- Review Requests → 관리자가 kubectl로 처리할 수 있다.
- Approve Requests → 관리자가 kubectl로 처리할 수 있다.
openssl genrsa -out jane.key 2048
openssl req -new -key jane.key -sunj "/CN=jane" -out jane.csr
# 인증서 사인 요청 개체를 생성
cat jane.csr | base64
# 인코딩하고, 이를 CertificateSigningRequest yaml 파일에 담는다.
# jane-csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: jane
spec:
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 600 # seconds
usages:
- digital signature
- key encipherment
- server auth
request:
# base64로 인코딩된 csr 파일 내용
관리자의 승인
kubectl get csr
kubectl certificate approve jane # 승인 명령어
kubectl certificate deny agent-smith # 거절 명령어
CSR-Approving & CSR-Signing
이 작업은, Controller Manager가 한다. Kube-Apiserver가 할 줄 알았는데… 의외였다.
kubeconfig
./kube/config
에 위치하고 있는 파일. cluster - context - user 구조로 이루어져 있다.
API Groups
쿠버네티스 kube-apiserver가 제공하는 api에는 대표적으로 /api
와 /apis
가 있다.
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
kubectl proxy
kubectl proxy를 이용하면, proxy가 인증서 파일을 가져다 사용하기 때문에 proxy를 사용하는 상태에서는 인증서 파일을 따로 명시해주지 않아도 바로 kube-apiserver에 인증 명령어 없이도 요청을 날릴 수 있게 된다.
Authorization
접속하고 나서, 뭘 할 수 있는가?가 인가의 정의이다.
우리는 지금까지 Admin으로 들어와서 모든 작업을 처리할 수 있었다. 그런데 다른 사람이 클러스터에 엑세스하고자 한다면? 혹은 다른 어플리케이션이 들어와서 클러스터에 접근하려고 한다면? 접근할 수 있게 해줘야 하지만, 접근 가능한 권한에는 차이를 두고 싶을 것이다. 클러스터를 서로 다른 조직이나 팀으로 나누어 공유할 때 논리적으로 네임스페이스를 이용해 분할해 사용자 접근을 제한할 수 있다. 클러스터 내에서의 권한은 이러한 작업을 가능하게 한다.
- Node Authorization
- ABAC
- RBAC
- Webhook
Node Authorizer
- kubelet은 apiserver에 엑세스해 서비스, 노드, 팟에 대한 정보를 읽고, apiserver에 노드에 대한 정보를 보고한다. 이러한 노드들의 apiserver에 대한 접근 권한은 Node Authorizer가 처리한다. kubelet은 SystemNodeGroup의 일부다. System Node Group의 일부인
ABAC (Attribute Based Access Control)
사용자, 리소스, 속성, 환경에 따라 권한을 결정한다.
ABAC은 관리하기 어렵다. 정책이 바뀔 때마다 정의 파일을 수정하고, kube-apiserver를 재시작해야 한다.
{"kind": "Policy", "spec": {"user": "dev-user", "namespace":"*", "resource":"pods", "apiGroup: "*"}}
{"kind": "Policy", "spec": {"user": "dev-user-2", "namespace":"*", "resource":"pods", "apiGroup: "*"}}
{"kind": "Policy", "spec": {"user": "dev-users", "namespace":"*", "resource":"pods", "apiGroup: "*"}}
{"kind": "Policy", "spec": {"user": "security-1", "namespace":"*", "resource":"csr", "apiGroup: "*"}}
RBAC (Role Based Access Control)
역할을 기준으로 권한을 결정한다. 쿠버네티스 클러스터 내에서 엑세스 관리에 대한 표준적 접근법을 제공한다.
Webhook
모든 승인 메커니즘을 외부에 위임하고자 할 때 사용한다. Open Policy Agent를 활용하면 kube-apiserver가 인가 내용이 필요할 때, Open Policy Agent에게 인가 여부를 물어보게 만들 수 있다.
AlwaysAllow, AlwaysDeny
승인 확인 없이 모두 허용하거나 모두 거부하는 모드이다.
앞서 살펴본 인가 모드들은 kube-apiserver를 시작할 때, --authorization-mode=<mode-name>
옵션으로 설정할 수 있다. 쉼표를 이용해 여러 모드를 사용할 수 있다. 지정된 순서대로 각각의 요청을 사용할 권한이 부여된다.
--authorization-mode=Node,RBAC,Webhook
사용자가 요청을 보내면 Node Authorizer가 먼저 처리하는데, 거부될 때마다 다음 모듈로 넘어가 다시 인가 절차를 거친다. Node Authorizer가 거부하면 RBAC에서 처리하고, 그다음은 Webhook에서 처리한다.
RBAC
역할을 만든다. Role 파일에서는 해당 역할이 어떤 리소스에 어떤 행동(verb)을 취할 수 있는지를 결정한다.
# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get", "create", "update", "delete"]
- apiGroups: [""]
resources: ["ConfigMap"]
verbs: ["create"]
역할을 사용자에게 Binding하는 RoleBinding 파일을 만든다.
dev-user라는 사용자는 이제 developer의 Role을 가지게 되어 developer Role에서 지정한 권한을 행사할 수 있다. 네임스페이스를 제한하고 싶다면, metadata 안에서 namespace를 지정하면 된다.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: devuser-developer-binding
subjects: # 사용자 세부 정보를 지정하는 곳
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef: # 롤의 세부 정보를 지정하는 곳
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
kubectl get roles
kubectl get rolebindings
kubectl describe role developer
kubectl describe rolebinding devuser-developer-binding
Check Access
kubectl auth can-i create deployments
kubectl auth can-i delete nodes
kubectl auth can-i create deployments --as dev-user
kubectl auth can-i create pods --as dev-user
Resource Names
만약 전체 파드가 아니라, 일부 파드만 접근 권한을 주고 싶다면 Resource Names를 사용할 수 있다.
# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get", "create", "update", "delete"]
- apiGroups: [""]
resources: ["ConfigMap"]
verbs: ["create"]
resourceNames: ["blue", "orange"]
Cluster Roles and Role Bindings
Role은 하나의 namespace 내에서만 동작한다. namespace를 지정하지 않으면, 기본 namespace에서 동작하게 된다. 네임스페이스는 격리에 도움이 되는 존재다. 그렇다면 노드는 어떻게 관리하나? 노드는 네임스페이스에 종속되지 않는다. 노드는 클러스터 범위의 리소스다.
리소스는 네임스페이스와 클러스터 스코프로 분리된다.
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=false
# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-administrator
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "get", "create", "delete"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-role-binding
subjects: # 사용자 세부 정보를 지정하는 곳
- kind: User
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
roleRef: # 롤의 세부 정보를 지정하는 곳
kind: ClusterRole
name: cluster-administrator
apiGroup: rbac.authorization.k8s.io
클러스터롤은 네임스페이스 스코프의 권한도 만들 수 있다.
kubectl get clusterroles --no-headers | wc -l
kubectl get clusterroles --no-headers -o json | jq '.items | length'
Service Accounts
쿠버네티스에는 User Account와 Service Account가 있다. User Account는 사람을 위한 시스템이고 ServiceAccount는 프로그램이 쿠버네티스와 상호작용할 때 사용한다. 프로메테우스 같은 것들이 있다.
kubectl create serviceaccount dashboard-sa
kubectl get serviceaccount
ServiceAccount를 생성하면 토큰이 자동으로 생성된다. 토큰은 외부앱이 쿠버네티스 API에 인증하는 동안 사용된다. 토큰은 Secret 객체로 저장된다. ServiceAccount가 생성되면, ServiceAccount를 위한 토큰이 생성되고, Secret을 만들어 토큰을 저장한다. Secret은 ServiceAccount에 링크된다.
kubectl describe secret dashboard-sa-token-kbbdm
토큰은 Header Authorization Bearer를 이용해 넘길 수 있다. 서비스 계정을 만들고, RoleBased Access Control 매커니즘을 사용할 수 있다.
모든 네임스페이스는 default serviceaccount를 자동으로 생성한다. 파드가 생성될 때마다 default 토큰이 자동으로 볼륨 마운트된다. 파드 내의 /var/run/sercrets/kubernetes.io/serviceaccount
경로를 확인하면 serviceaccount token 파일을 확인할 수 있다. default serviceaccount는 매우 기본적인 쿠버네티스 API 쿼리를 실행하는 권한만 가지고 있다. 다른 serviceaccount를 사용하고 싶다면 pod definition yaml에서 serviceAccountName으로 설정해줄 수 있다.
v1.22 개선 내용 - KEP 1205
v1.22에서 default로 생성되는 serviceaccount token은 제한 기간이 없다. 그리고 각 serviceaccount당 token을 담기 위한 1개의 별개의 secret을 필수적으로 요구한다.
KEP 1205를 통해 serviceaccount token 개선안이 제시되었다.
- Audience Bound
- Time Bound
- Object Bound
v1.22 이후로는 정해진 수명을 가진 해당 Pod를 위한 token이 TokenRequestAPI를 통해 생성된다.
v1.24 개선 내용 - KEP 2799
과거에는 serviceaccount가 생성되면, 만료되지 않는 토큰이 secret으로 생성되었고, 이 토큰은 해당 serviceaccount를 사용하는 파드에 자동으로 마운트되었다. 하지만 v1.22에서는 자동으로 secret을 파드에 volume으로 마운트하는 대신, TokenRequestAPI를 사용해 만료기간이 있는 토큰을 발급해 마운트하도록 변경되었다.
따라서, serviceaccount를 생성하고, 이제는 토큰을 별개로 생성해야 한다. 토큰을 해독해보면 만료 기간이 정의된 것을 확인할 수 있다. 추가 옵션을 통해 만료 기간을 늘릴 수 있다.
kubectl create serviceaccount dashboard-sa
kubectl create token dashboard-sa # 토큰을 화면에 프린트함
jq -R 'split(".") | select(length > 0) | .[0],.[1] | @base64d | fromjson' <<< (앞서프린트된토큰)
# 토큰을 JSON 형태로 해독
v1.24에서 만료되지 않는 토큰을 만들고 싶다면, secret을 만들어 해결할 수 있다.
# 만료되지 않는 토큰 만들기 (서비스어카운트를 먼저 생성하고 시크릿을 만들어야 함)
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: mysecretname
annotations:
kubernetes.io/service-account.name: dashboard-sa
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: dashboard-sa # Name is case sensitive
namespace: default
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups:
- ''
resources:
- pods
verbs:
- get
- watch
- list
기존 deployment에 serviceaccount 추가하기
kubectl set serviceaccount deploy/web-dashboard dashboard-sa
spec.template.spec.serviceAccountName: dashboard-sa
Image Security
image: nginx
docker.io/library/nginx
docker.io -> registry
library -> UserAccount
nginx -> ImageRepository
nginx는 무엇일까? → Image Repository를 뜻한다.
쿠버네티스 클러스터는 어떻게 Private Registry에 접근할 Credentials를 확인하는가?
kubectl create secret deocker-registry regcred \
--docker-server=private-registry.io \
--docker-username=registry-user \
--docker-password=registry-password \
--docker-email=registry-user@org.com
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: regcred
Security Contexts
도커 컨테이너는 고유 네임스페이스에 존재하고 있다. 그래서 자신의 고유 프로세스만 볼 수 있다. 바깥이나 다른 네임스페이스에 대해서는 아무 것도 알 수 없다.
도커 호스트에서 하위 네임스페이스에 있는 모든 프로세스는 전부 프로세스로 보인다. 단, 도커 컨테이너 내에서 보이는 PID와 도커 호스트에서 보이는 동일한 프로세스에 대한 PID는 다르게 보인다.
→ 프로세스는 다른 네임스페이스에서는 다른 프로세스ID를 가질 수 있다. (프로세스 격리)
도커 호스트는 사용자 집합을 갖고 있다. 루트 유저와 비루트 유저들. 도커는 루트 사용자로써 컨테이너 내의 프로세스를 실행한다. 도커 안과 밖에서 프로세스는 루트 사용자로 실행된다. 컨테이너 내의 프로세스가 루트 사용자로 실행되길 원하지 않는다면 Docker 실행 명령 안에서 사용자 옵션을 사용해 새 사용자 ID를 명시할 수 있다.
docker run --user=1000 ubuntu sleep 3600
사용자 보안을 시행하는 다른 방법은, 도커 이미지 자체에서 생성 시 사용자를 정의하는 방법이 있다.
# Dockerfile
FROM ubuntu
USER 1000
docker build -t my-ubuntu-image .
docker run my-ubuntu-image sleep 3600
루트 유저로써 컨테이너를 실행하면 어떻게 될까? 컨테이너 안의 루트 사용자와 호스트의 루트 사용자는 같은 인물인가? 컨테이너 안의 실행된 프로세스도 루트 사용자가 시스템에서 할 수 있는걸 시행할 수 있는가? 그렇다면 보안 문제가 있지 않나?
도커는 컨테이너 내 루트 사용자의 능력을 제한하는 보안 기능 집합을 구현한다. 컨테이너 안의 루트 사용자는 호스트의 루트 사용자와는 다른 존재다. 루트 사용자는 시스템의 모든 것을 할 수 있다. 그리고 루트에 의해 실행된 프로세스도 마찬가지로 시스템에 대한 모든 것을 처리할 수 있다. 어떻게 제한하는가? 기본 값으로 도커는 컨테이너를 실행하는데, 제한된 기능만을 시행할 수 있게끔 되어 있다. 재부팅, 어드민 등의 권한을 제외했다. 만약 이 권한을 재정의하고 싶다면 --cap
옵션을 사용해 권한을 수정할 수 있다.
docker run --cap-add MAC_ADMIN ubuntu
docker run --cap-drop KILL ubuntu
docker run --privileged ubuntu # 전체 권한 부여
쿠버네티스는 컨테이너를 파드로 캡슐화한다. 컨테이너 레벨이나 파드 레벨에서 보안 설정을 진행할 수 있다.
파드 레벨에서 보안을 설정하면, 파드 내의 모든 컨테이너가 영향을 받는다.
파드 레벨과 컨테이너 레벨의 보안을 둘 다 설정하면, 컨테이너 레벨이 파드 레벨을 덮어쓴다.
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
securityContext: # 파드 레벨
runAsUser: 1000 # 유저 설정
containers:
- name: ubuntu
image: ubuntu
command: ["sleep", "3600"]
securityContext: # 컨테이너 레벨
runAsUser: 1000 # 유저 설정
capabilities:
add: ["MAC_ADMIN"]
컨테이너나 파드가 어떤 권한으로 실행되었는지 알려면 다음 명령어를 사용하면 된다.
kubectl exec ubuntu-sleeper -- whoami
Network Policy
쿠버네티스 네트워킹의 전제 조건 중 하나는 어떤 솔루션을 구현하든, 추가적인 설정 없이 파드가 서로 통신할 수 있어야 한다는 것이다.
쿠버네티스는 기본값으로 모든 팟과 서비스에 대해서 AllAlow 규칙으로 구성된다.
파드 간 통신을 가능하게 하거나, 불가능하게 하기 위해서 Network Policy를 설정하게 된다. Network Policy는 쿠버네티스의 리소스 중 하나로, 파드의 네트워크 규칙을 관리한다. Network Policy 안에서 규칙을 정의할 수 있다.
kubectl get netpol
apiVersion: netwokring.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress # Allow Ingress
ingress:
- from: # From API-Prod Pod
- podSelector:
matchLabels:
name: api-prod
ports: # On TCP 3306 Port
- protocol: TCP
port: 3306
NetworkPolicy를 지원하는 구현체
- KubeRouter, Calico, Romana, Weave-net
- Flannel은 지원하지 않음!!
EXAMPLE - DB Pod 관리하기
이미지 출처: Certified Kubernetes Administrator (CKA) with Practice Tests(Udemy)
apiVersion: netwokring.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
ports:
- protocol: TCP
port: 3306
- 현재는 모든 api-pod 이름의 팟이 DB에 접근할 수 있는데, 특정 네임스페이스만 접근 가능하게 하고 싶다면? 아래의 코드를 yaml 파일에 추가해준다.
apiVersion: netwokring.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: prod
ports:
- protocol: TCP
port: 3306
EXAMPLE2 - BackupServer to DB Pod
만약 클러스터 외부의 서버가 DB에 접근하고 싶다면?
특정 IP 주소에서 접근할 수 있도록 Network Policy를 추가할 수 있다.
apiVersion: netwokring.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: prod
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 3306
podSelector와 namespaceSelector는 하나의 Array 요소 안에 들어있다. 즉 이 둘은 AND 연산으로 동작한다. 하지만 ipBlock은 다른 Array 요소이므로, OR로 동작한다.