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 사용법 정리
- Create Network Namespace
- Create Bridge Network/Interface
- Create VETH Pairs(Pipe, Virtual Cable)
- Attach vEth to Namespace
- Attach Other vEth to Bridge
- Assign IP Address
- Bring the interfaces up
- 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
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
아래와 같이 서비스들에 접근할 수 있음
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 |