본 포스팅은 CKA 자격증 준비를 위해 해당 강의를 보고 정리한 자료입니다.
일부 생략되었으니 꼭 강의를 수강하시고 내용 정리 용도로만 참고하시길 바랍니다.
Pod Networking
pod들이 어떻게 주소가 할당되고 어떻게 서로 통신할까? 클러스터 내부, 외부에서 pod에서 돌고있는 서비스에 어떻게 접근할까? 우선 쿠버네티스는 이것에 대해 자체적으로 solution을 제공하지는 않는다.
쿠버네티스는 모든 pod들이 unique한 ip 주소를 가지고, 해당 ip를 통해 같은 node의 모든 pod들이 서로 통신할 수 있도록 한다.
1. 노드에 container가 생성되면, 네트워크 namespace를 생성한다. 쿠버네티스는 통신을 위해 namespace를 network에 붙인다. 여기서 말하는 네트워크는 bridge network를 말한다. 즉, 각 노드에 bride network를 생성한다.
2. 각 bridge network, bridge interface에 ip주소를 할당한다.
3. 컨테이너를 네트워크에 붙인다. pipe 또는 virtual network cable을 사용한다. ip link add 명령어를 통해 생성할 수 있다.
-> pod들이 unique ip를 가졌으며 서로 통신할 수 있다. 다른 노드의 pod과 통신하기 위해서는 아래의 과정이 필요하다.
4. routing table을 이용해 모든 호스트에 대해 route를 구성한다.
5. 위 과정을 manual하게 script로 정의하지 않고 자동으로 하기위해 CNI가 도입되었다. CNI 표준에 맞추어 정의하면, 실제로는 CNI를 통해 위 과정이 수행된다.
CNI in kubernetes
kubelet 정보를 통해 cni 설정 정보를 확인할 수 있다.
$ ps -aux | grep kubelet
- --network-plugin=cni : kubelet 실행시 받은 cni 설정 정보
- --cni-bin-dir : cni 플러그인 파일 디렉토리
- --cni-conf-dir :cni 설정 파일 디렉토리
→ kubelet은 해당 정보들로 cni script의 add 명령어를 수행해 네트워크를 구성하게 된다.
CNI weave
routing table 은 수많은 entry를 지원할 수 없다. 클러스터 내 노드가 엄청 많고 각 노드에 pod이 엄청 많은 큰 환경에서는 다른 솔루션이 필요하다. 이를 weave 등 CNI plugin을 통해 해결할 수 있다.
weave CNI plugin이 클러스터에 배포되면, plugin이 각 노드에 agent 또는 service를 배포한다. 그들은 노드, network, pod에 대한 정보를 교환하기위해 서로 통신한다. 각 agent 또는 peer는 전체 설정의 topology를 저장하고, 그렇게 하면 다른 노드에 있는 pod과 해당 ip를 알 수 있다. weave는 노드들에 그만의 bridge를 만들고 weave라고 이름짓는다. 그리고 각 network에 ip주소를 할당한다.
하나의 pod이 여러개의 bridge network에 붙을 수 있다. 예를 들어 pod이 docker가 만든 docker bridge 뿐만 아니라 weav bridege에도 붙을 수 있다. 패킷이 대상에 도달하기 위해 사용하는 경로는 컨테이너에 구성된 경로에 따라 다르다. weave는 pod들이 agent에 도달할 수 있도록 구성된 올바른 경로를 확보하도록 한다. 그리고 agent가 다른 pod들을 처리한다. 패킷이 하나의 pod에서 다른 노드의 다른 pod으로 보내지면, weave는 패킷을 가로채고 별도의 network에 있음을 확인한다. 그런 다음 이 패킷을 새로운 소스 및 대상이 있는 새 패킷으로 캡슐화하고 네트워크를 통해 전송한다. 다른 쪽에서는, 다른 weave agent가 패킷을 검색하고 분해하여 패킷을 올바른 pod으로 라우팅하게 된다.
IP Address Management
POD IP를 중복되지 않도록 할당하는 방법
가장 간단한 방법은 ip 리스트를 파일로 저장하는 것이다. 이 파일을 각 host에 두고 ip를 관리할 수 있다. 하지만 CNI를 통해 다른 방식으로 관리할 수 있다.
weave가 ip 주소를 관리하는 방법
weave는 전체 network에 10.32.0.0/12 에 해당하는 범위에서 ip를 할당한다. 이는 10.32.0.1 ~ 10.47.255.254 범위에 해당한다. peer가 ip주소를 동등하게 분할하여 각 노드에 할당한다. 해당 노드에서 생성된 pod은 해당 범위를 가지게 된다.
Service Networking
서비스를 생성하면 다른 노드에 있는 pod에도 접근할 수 있다. 하지만, 클러스터내에서만 접근가능하다. 이런 서비스 타입은 ClusterIP이다. 클러스터 외부에서 접근할 수 있도록 노드의 port를 노출하는 방법은 NodePort 타입이다. 그렇다면 서비스들이 ip 주소를 어떻게 가지며 ip가 클러스터의 모든 노드에 걸쳐 가능하도록 만들어지는 걸까?
각 노드에는 kube-proxy가 돌고있다. kube-proxy는 kube-apiserver를 통해 클러스터 내 변화를 관찰하고 있다. 새로운 서비스가 생성될 때마다 kube-proxy가 작동한다. pod과 달리 서비스는 cluster 범위의 컨셉이다. 그들은 클러스터 내 모든 노드에 걸쳐 존재한다. (물론 실제로 존재하는 객체는 아니다. 가상의 object에 불과하다.)
서비스가 생성되면, 미리 정의된 범위 내에서 ip 주소가 할당된다. 각 노드에서 돌고있는 kube-proxy는 ip를 가져와 클러스터 내 각 노드에 forwarding rule을 생성한다. (특정 ip로 들어오는 트래픽을 특정 ip로 보내는 rule)
그렇다면 어떻게 kube-proxy가 이 rule들을 생성할까? 여기에는 userpace, iptables, ipvs 세 가지 방법이 있다. default는 iptables이다.
$ kube-proxy --proxy-mode [userspace | iptables | ipvs] ...
서비스를 생성했을 때 할당되는 cluster-ip는 kube-apiserver 옵션을 통해 정의된 범위 내에서 할당된다.
kube-proxy에 의해 생성된 rule은 다음 명령어로 확인 가능하다.
$ iptables -L -t nat | grep {SERVICE NAME}
DNS
쿠버네티스는 기본적으로 built-in DNS 서버를 배포한다. service가 생성되면 쿠버네티스 DNS 서버는 service를 위한 record를 생성한다. 이는 service 이름과 ip 주소를 매핑한다. 따라서 클러스터내 어느 pod이던 service 이름을 통해 접근할 수 있다. service가 다른 namespace에 존재하면, {Service Name}.{Namespace}로 domain이 생성된다.
✔ 기본적으로 생성되는 domain name
Service
{Service Name}.{Namespace}.svc.cluster.local
Pod
{POD IP with dash}.{Namespace}.svc.cluster.local
CoreDNS in kubernetes
- 쿠버네티스가 1.12 버전 부터 추천/배포하는 DNS 서버
- 클러스터에 kube-system namespace에 배포됨
- CoreDNS 설정은 /etc/coredns/Corefile 에 정의됨
- 수 많은 plugin들이 정의되는데, 그 중 CoreDNS가 쿠버네티스와 동작하도록하는 부분은 'kubernetes' 부분
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
proxy . /etc/resolv.conf
cache 30
reload
}
-
- 이 corefile은 pod에 configmap으로 전달됨
- pod이 CoreDNS 서버를 가리키게 하는 방법
- pod이 DNS 서버에 접근하기 위해 사용하는 주소는 무엇일까?
- 기본적으로 kube-dns라는 이름으로 서비스가 배포되고, 이 서비스의 주소가 pod에 nameserver로 구성된다.
- kubelet config file을 보면 DNS 서버 주소를 볼 수 있다. (/var/lib/kubelet/config.yaml)
- pod이 DNS 서버에 접근하기 위해 사용하는 주소는 무엇일까?
Ingress
참고: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-ingress-em-
ingress는 클러스터 바깥으로부터 서비스에 HTTP 또는 HTTPS 를 노출한다. 즉, 외부에서 접근가능한 URL을 구성할 수 있다. 동시에 SSL 보안 설정도 제공한다.
ingress를 위해서 사전적으로 ingress controller가 필요하다. ingress-nginx 같은 ingress controller를 배포해야하며 여러 controller 중에 선택하면 된다.
Ingress Resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wear-watch
spec:
rules:
- http:
paths:
- path: /wear
backend:
service:
name: wear-service
port:
number: 80
- path: /watch
backend:
service:
name: watch-service
port:
number: 80
- wear-service 서비스 80 port에 /wear path로 접근 가능하도록 한다.
- watch-service 서비스 80 port에 /watch path로 접근 가능하도록 한다.
apiversion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wear-watch
spec:
rules:
- host: wear.my-online-store.com
http:
paths:
- backend:
service:
name: wear-service
port:
number: 80
- host: watch.my-online-store.com
http:
paths:
- backend:
service:
name: watch-service
port:
number: 80
Imperative Command
$ kubectl create ingress <ingress-name> --rule="host/path=service:port"
$ kubectl create ingress <ingress-name> --rule="wear.my-online-store.com/wear*=wear-service:80"
'DevOps > Kubernetes' 카테고리의 다른 글
K8s PLG Stack (Promtail + Loki + Grafana) (0) | 2023.04.23 |
---|---|
[CKA] CKA 합격 후기 (2021.12 - kubernetes v1.21) (12) | 2021.12.25 |
[CKA] CKA 자격증 준비 자료 정리 7 (Storage) (0) | 2021.12.18 |
[CKA] CKA 자격증 준비 자료 정리 6 (Security) (0) | 2021.12.16 |
[CKA] CKA 자격증 준비 자료 정리 5 (Cluster Maintenance) (0) | 2021.12.11 |