- CKA 시험 비중 (20%)
- Pod Network
CNI에서 관리하는 포드 간 통신에 사용되는 클러스터 전체 네트워크
- Service Network
Service discovery를 위해 kube-proxy가 관리하는 Cluster-wide 범위의 Virtual IP(Cluster IP)
부하분산, Web 단일진입점(LB) Kubernetes Network Proxy 각각의 Node에서 실행되고, Kubernetes Service API에 정의된 서비스를 각 노드에서 반영 (kube-proxy 역할: iptables rule을 설정하고 외부 네트워크와 Pod를 연결)
- Service Type - ClusterIP(default)
* Pod 그룹(동일한 서비스를 지원하는 Pod 모음)의 단일 진입점 (Virtual IP:LB) 생성
* Selector의 label이 동일한 Pod들을 그룹으로 묶어 단일 진입점 (Virtual IP:LB) 생성
* 클러스터 내부에서만 사용가능
* Service Type 생략 시 deafult로 설정
* 랜덤하게 10.96.0.0/12 범위에서 할당 -> 고정으로도 설정 가능
- 실습
- 동일한 서비스를 제공하는 Pod 그룹에 ClusterIP 생성하기
deployment name: web, image: nginx, port:80, replicas:2
service name: web, type: clusterIP, port: 80
$ kubectl create deployment web --image=nginx --port=80 --replicas=2 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources: {}
status: {}
$ kubectl create deployment web --image=nginx --port=80 --replicas=2
deployment.apps/web created
$ kubectl get pod -o wide | grep web
web-cff6559d7-72lmx 1/1 Running 0 4m46s 10.244.2.2 minikube-m03 <none> <none>
web-cff6559d7-qfc4x 1/1 Running 0 4m46s 10.244.3.2 minikube-m04 <none> <none>
$ kubectl expose deployment web --type=ClusterIP --port=80 --target-port=80 --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: web
type: ClusterIP
status:
loadBalancer: {}
$ kubectl expose deployment web --type=ClusterIP --port=80 --target-port=80
service/web exposed
$ kubectl get svc web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP 10.105.239.84 <none> 80/TCP 15s
$ kubectl exec ${Pod Name} -i -t -- bash -il
$ root@web-cff6559d7-72lmx:/# curl 10.105.239.84
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- Service Type - NodePort
* ClusterIP가 생성된 후 모든 Worker Node에 외부에서 접속 가능한 포트가 예약
* 모든 노드를 대상으로 외부 접속 가능한 포트를 예약
* Default NodePort 범위: 30000-32767
* ClusterIP를 생성 후 NodePort를 예약
- Network Policy
* Kubernetes가 지원하는 Pod 통신 접근 제한
* 일종의 방화벽으로 Pod로 트래픽이 들어오고(Inbound), 나가는(Outbound) 것을 설정하는 정책
* Ingress 트래픽: Inbound 정책. 들어오는 트래픽을 허용할 것 인지 정의
* Egress 트래픽: Outbound 정책. 트래픽이 나갈 수 있는 허용 범위 정의
트래픽 컨트롤 정의
* ipBlock: 특정 IP 대역에서만 들어오는 트래픽만 받을 수 있다.
* podSelector: 특정 label을 가지고 있는 Pod들에서 들어오는 트래픽만 받을 수 있다.
* namespaceSelector: 특정 namespace로부터 들어오는 트래픽만 받을 수 있다.
* Protocol & Port: 특정 Protocol 또는 Port로 설정된 트래픽만 받을 수 있다.
- 실습
- app: web 레이블을 가진 Pod에 특정 namespace의 Pod들만 접근 허용
$ kubectl run webpod --image=nginx --port=80 --labels=app=web --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
app: web
name: webpod
spec:
containers:
- image: nginx
name: webpod
ports:
- containerPort: 80
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
$ kubectl run webpod --image=nginx --port=80 --labels=app=web
pod/webpod created
$ kubectl get pod -o wide webpod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webpod 1/1 Running 0 9s 10.244.3.3 minikube-m04 <none> <none>
$ kubectl create namespace dev
namespace/dev created
$ kubectl create namespace prod
namespace/prod created
$ kubectl label namespaces prod purpose=production
namespace/prod labeled
$ kubectl label namespaces dev purpose=development
namespace/dev labeled
$ kubectl get namespaces -L purpose
NAME STATUS AGE PURPOSE
default Active 16d
dev Active 43s development
grafana Active 13d
ingress-nginx Active 16d
kube-node-lease Active 16d
kube-public Active 16d
kube-system Active 16d
prod Active 41s production
$ kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 16d kubernetes.io/metadata.name=default
dev Active 59s kubernetes.io/metadata.name=dev,purpose=development
grafana Active 13d kubernetes.io/metadata.name=grafana
ingress-nginx Active 16d app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,kubernetes.io/metadata.name=ingress-nginx
kube-node-lease Active 16d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 16d kubernetes.io/metadata.name=kube-public
kube-system Active 16d kubernetes.io/metadata.name=kube-system
prod Active 57s kubernetes.io/metadata.name=prod,purpose=production
$ vi web-allow-prod.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow-prod
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: production
ports:
- protocol: TCP
port: 80
$ kubectl apply -f web-allow-prod.yaml
networkpolicy.networking.k8s.io/web-allow-prod created
$ kubectl get networkpolicies
NAME POD-SELECTOR AGE
web-allow-prod app=web 18s
$ kubectl describe networkpolicies
Name: web-allow-prod
Namespace: default
Created on: 2023-05-07 18:02:33 +0900 KST
Labels: <none>
Annotations: <none>
Spec:
PodSelector: app=web
Allowing ingress traffic:
To Port: 80/TCP
From:
NamespaceSelector: purpose=production
Allowing egress traffic:
<none> (Selected pods are isolated for egress connectivity)
Policy Types: Ingress, Egress
$ kubectl run testpod -it --rm --image=centos:7 -n dev -- /bin/bash
- Ingress
* L7(애플리케이션 계층) 스위치 역할을 논리적으로 수행
* 클러스터로 접근하는 URL 별로 다른 서비스에 트래픽을 분산
* Service에 외부 URL을 제공, 트래픽을 로드밸런싱, SSL 인증서 처리, Virtual Hosting 지정
- Core DNS
* 쿠버네티스 클러스터에서 사용하는 DNS
* 클러스터 내의 모든 Service에는 DNS 네임이 할당
* 클러스터에서 동작되는 모든 Pod의 /etc/resolv.conf에는 kube-dns가 namespace로 정의되어 있다.
cat /etc/resolv.conf
nameserver 10.96.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
* 특정 Pod에서 service name이나 pod name으로 접근 가능
- 실습
- Core DNS 테스트
$ kubectl create deployment web --image=nginx --port=80 --replicas=2
deployment.apps/web created
$ kubectl expose deployment web --port=80
service/web exposed
$ kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web 2/2 2 2 24s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m
web ClusterIP 10.103.65.140 <none> 80/TCP 16s
$ kubectl run dns-test --image=busybox -it --rm -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/ # nslookup 10.103.65.140
Server: 10.96.0.10
Address: 10.96.0.10:53
140.65.103.10.in-addr.arpa name = web.default.svc.cluster.local
- 실습
- image nginx를 사용하는 resolver pod를 생성하고, resolver-service라는 service를 구성합니다.
- 클러스터 내에서 service와 pod 이름을 조회할 수 있는지 테스트합니다.
dns 조회에 사용하는 pod 이미지는 busybox이고, service와 pod 이름 조회는 nslookup을 사용합니다.
service 조회 결과는 nginx.svc에 pod name 조회 결과는 nginx.pod 파일에 기록합니다.
$ kubectl run resolver --image=nginx
pod/resolver created
$ kubectl expose pod resolver --port=80 --name=resolver-service
service/resolver-service exposed
$ kubectl get pod resolver
NAME READY STATUS RESTARTS AGE
resolver 1/1 Running 0 37s
$ kubectl get pod resolver -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
resolver 1/1 Running 0 40s 10.244.0.10 minikube <none> <none>
$ kubectl get svc resolver-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
resolver-service ClusterIP 10.111.159.14 <none> 80/TCP 29s
$ kubectl run test --image=busybox -it --rm -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # nslookup 10.244.0.10
Server: 10.96.0.10
Address: 10.96.0.10:53
10.0.244.10.in-addr.arpa name = 10-244-0-10.resolver-service.default.svc.cluster.local
/ # nslookup 10.111.159.14
Server: 10.96.0.10
Address: 10.96.0.10:53
14.159.111.10.in-addr.arpa name = resolver-service.default.svc.cluster.local
/ # exit
Session ended, resume using 'kubectl attach test -c test -i -t' command when the pod is running
pod "test" deleted
$ vi nginx.pod
$ vi nginx.svc
$ cat nginx.pod
Server: 10.96.0.10
Address: 10.96.0.10:53
10.0.244.10.in-addr.arpa name = 10-244-0-10.resolver-service.default.svc.cluster.local
$ cat nginx.svc
Server: 10.96.0.10
Address: 10.96.0.10:53
14.159.111.10.in-addr.arpa name = resolver-service.default.svc.cluster.local
'CKA' 카테고리의 다른 글
[CKA] Cluster Architecture, Installation & Configuration (2) (0) | 2023.05.14 |
---|---|
[CKA] Cluster Architecture, Installation & Configuration (1) (0) | 2023.05.13 |
[CKA] Troubleshooting (0) | 2023.05.13 |
[CKA] 실습 환경 구성하기 (Mac) (0) | 2023.05.02 |
[CKA] 자격증이란? (0) | 2023.03.15 |