[CKA] 11일차 network(2) - CNI, Ingress, CoreDNS

docker networking

docker run --network none nginx # 네트워킹을 하지 않음
docker run --network host nginx # host 네트워크를 사용함
디폴트로는 bridge가 PC 내에 생성되면서, docker가 bridge에 붙음

bridge가 생성되는 건

ip link add docker0 type bridge

명령어를 입력한 것과 같음

ip netns

명령어를 입력하면 container가 network namespace 를 가지게 된 것을 확인할 수 있음

ip link
ip netns
docker inspect <docker id>
ip -n b3165c10a92b link

docker에서 port mapping을 하는 방식

iptables \
  -t nat \
  -A PREROUTING \
  -j DNAT \
  --dport 8080 \
  --to-destination 80

docker run -p 8080:80 nginx

iptables \
  -t nat \
  -A DOCKER \
  -j DNAT \
  --dport 8080 \
  --to-destination 172.17.0.3:80

룰을 다음과 같이 확인할 수 있음
iptables -nvL -t nat

network namespace 사용법 정리

  1. Create Network Namespace
  2. Create Bridge Network/Interface
  3. Create VETH Pairs(Pipe, Virtual Cable)
  4. Attach vEth to Namespace
  5. Attach Other vEth to Bridge
  6. Assign IP Address
  7. Bring the interfaces up
  8. Enable NAT - IP Masquerade

이런 것들이 bridge라는 application에 구현이 되어 있음

CNI

CNI(Container Network Interface)

위와 같이 network namespace 사용법, docker, rkt, mesaos, kubernetes 등의 network 사용법이 같기 때문ㅇ
CNI로 인터페이스를 묶을 수 있음

docker는 CNI가 아닌 CNM(Container Network Model)을 사용하기 때문에
docker run --network=cni-bridge nginx 처럼 사용할 수 없음

기존 pod 네트워킹의 한계

pod 간의 네트워킹을 위해서 routing table에 추가를 하게 되는데,
routing table은 entry 한계가 있음
그래서 pod 개수가 늘어나면, 별도의 솔루션이 필요함

Deploy weave

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
kubectl get pods -n kube-system
kubectl logs weave-net-5gcmb weave -n kube-system

local에 설치된 kubelet 서비스 정보 보기

ps -aux | grep kubelet

  • cni의 bin: /opt/cni/bin
  • cni의 conf: /etc/cni/net.d

IP address 관리(IPAM)

각 pod의 할당되지 않은 IP를 별도의 텍스트로 관리하고 있음.
cat /etc/cni/net.d/net-script.conf


{
...
"ipam": {
  "type": "host-local",
  "subnet": "10.244.0.0/16",
  "routes": [
    { "dst": "0.0.0.0/0" }
  ]
}
...
}

weave가 ip를 관리하는 방법

10.32.0.0/12
10.32.0.1 > 10.47.255.254

여기 내에서 ip를 할당하도록 함

Service Network

  • clusterIP는 cluster 내의 어떤 pod에서도 접근 가능함
  • nodePort는 외부로 노출되는 ip임

node의 ip 할당 범위 확인

ip addr 에서 eth0의 범위를 확인

pod의 ip 할당 범위 확인

k logs weave -n kube-system

service의 ip 할당 범위 확인

cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep cluster-ip-range

kube-apiserver에서 실행할 때 service의 ip range가 명시되어 있음
- --service-cluster-ip-range=10.96.0.0/12

CoreDNS

아래와 같이 서비스들에 접근할 수 있음
..svc.cluster.local

coreDNS는 pod로 구성되어 있으며,
cat /etc/coredns/Corefile
파일을 읽었을 때 설정 파일을 확인할 수 있습니다.

Ingress(Layer 7 - Application Level Load Balancer라고 생각해도 됨)

ingress는 하나의 endpoint에서 /로 주소를 구분해서 트래픽을 분배할 수 있음
또한 SSL 설정도 쉽게 할 수 있음

ingress에서도 외부로 포트를 노출할 필요가 있는데,

  • nodePort
  • loadBalancer
    둘 중 하나로 노출해야 함

Ingress Controller

Ingress Controller는 다음과 같은 Load Balancer 툴을 설치해서 사용할 수 있음
GCP, Nginx, Contour, HAPROXY, traefic, Istio 등

nginx로 ingress controller를 구성하는 예시

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
spec:
  replicas:
  selectors:
    matchLabels:
      name: nginx-ingress
  template:
    metadata:
      labels:
        nginx-ingress
    spec:
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0
      args:
        - /nginx-ingress-controller
        - --configmap=$(POD_NAMESPACE)/nginx-configuration
      env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443

ingress controller를 만들 때 ConfigMap은 필요 없지만,
만들어두면 나중에 decoupling할 때 도움이 됨

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    name: nginx-ingress

ingress resources에 대해서 모니터링 하려면, SA(Service Account)가 필요함

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount

그리고 Roles, ClusterRoles, RoleBindings 가 필요함

ingress 세팅

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-wear
spec:
  backend:
    serviceName: wear-service
    servicePort: 80
kubectl create -f Ingress-wear.yaml
kubectl get ingress

만약 url의 path로 앱을 구분해서 라우팅하려고 한다면 다음과 같이 설정할 수 있습니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-wear-watch
spec:
  rules:
  - http:
      paths:
      - path: /wear
        backend:
          serviceName: wear-service
          servicePort: 80
      - path: /watch
        backend:
          serviceName: watch-service
          servicePort: 80

subdomain으로 분리하는 경우에는 다음과 같이 ingress 설정을 할 수 있습니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-wear-watch
spec:
  rules:
  - host: wear.my-online-store.com
    http:
      paths:
      - backend:
          serviceName: wear-service
          servicePort: 80
  - host: watch.my-online-store.com
    http:
      paths:
      - backend:
          serviceName: watch-service
          servicePort: 80

만약 host를 설정하지 않은 항목이 있으면, host에 매칭되지 않은 경우에 거기로 떨어짐

Ingress - Annotations and rewrite-target

예를 들어서 /pay라는 주소로 사용자가 들어왔을 때
해당 서비스의 /pay가 아닌 / 주소로 연결하고 싶다면,
다음과 같이 annotations를 추가해주면, 해당 서비스로 들어갈 때 path가 /로 치환됩니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: critical-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /pay
        backend:
          serviceName: pay-service
          servicePort: 8282

다른 예제로는 다음과 같이 사용할 수도 있습니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)

만약 http 로 라우팅했는데, 계속 https로 리다이렉트하는 현상이 있다면,
ingress의 metadata에 다음과 같이 추가해주면 됩니다.

annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"

'advanced > Devops' 카테고리의 다른 글

[CKAD] 1일차  (0) 2022.09.15
[CKA] 12일차 - HA 설정(ETCD 서버)  (0) 2022.09.02
[CKA] 10일차 - network(1) network 이론 및 network namespace  (0) 2022.08.26
[CKA] 9일차 - Storage (2) PV, PVC, SC  (0) 2022.08.22
[CKA] 8일차 - Storage  (0) 2022.08.21

댓글

Designed by JB FACTORY