일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ssh
- M365필터
- tar
- vgcreate
- yum
- MSBing
- docker image
- lvcreate
- HTTPD
- docker
- newbingai
- journalctl
- chmod
- 프로세스
- vagrant kubernetes
- pvcreate
- 랜카드인식불량
- 날짜변경
- firewalld
- permission
- chatGPT
- ansible
- swapon
- mount
- nmcli
- 엑셀파일명변경
- 같은폴더
- docker network
- Kubernetes
- 리다이렉션
- Today
- Total
becool
20210831 (화) kubernetes 내부,외부 네트워크 본문
9:34 review
Kubernetes 네트워크
Pod는 일회성으로 동작하며 유동적으로 (생성/추가/삭제) 운영됨
특정노드에 pod가 스케쥴링되고 IP주소를 동적으로 할당받으므로 클라이언트가 사전에 IP주소 예측불가
전통적인 방식에서 서버가 고정적인 ip(진입점)를 가졌던 것처럼, Service를 통한 진입점을 제공
- Kubernetes Cluster 내부 네트워크
- 서비스 (Service)
Kubernetes Cluster에서 애플리케이션을 실행하는 pod, controller에 대해 단일 네트워크 진입점을 제공하는 object
별도로 service object를 종료하지 않는 이상 부여된 IP주소가 변경되지 않음
Label Selector를 이용하여 service object 와 연결할 대상을 관리
Service에 선택된 pod의 목록은 Endpoint object가 관리
kubectl get services
kubectl expose CONTROLLER_TYPE CONTROLLER_NAME --name SERVICE_NAME
manifest작성 후 SERVICE_FILE_NAME.yaml → kubectl create -f SERVICE_FILE_NAME.yaml
- Session Affinity
Client 요청을 처음 요청한 pod와 동일한 pod에 세션을 유지하고자 할 때 사용
(하나의 pod와 지속적인 통신을 함으로써 데이터 손실이 발생하지 않게 함)
- Service (다중포트)
- 서비스 (named port)
##### named port #####
vagrant@kube-control1:~/work/20210831$ cat test-rs.yaml
#→ 레플리카셋 작성
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: test-rs
spec:
replicas: 5
selector:
matchLabels: #→ label이 일치하는 pods 대상
app: test-rs-namedport
template:
metadata:
labels: #→ label 작성
app: test-rs-namedport
spec:
containers:
- name: test
image: devops2341/go-myweb:latest
ports:
- name: test-http
containerPort: 8080
protocol: TCP
vagrant@kube-control1:~/work/20210831$ cat test-svc.yaml
#→ 서비스 작성
apiVersion: v1
kind: Service
metadata:
name: test-svc-namedport
spec:
ports:
- name: test-http
port: 80
targetPort: test-http #→ targetport를 문자로 표현
selector:
app: test-rs-namedport
- 서비스 탐색 (Service Discovery)
1) 환경변수를 이용한 Service Discovery
env 명령어를 통해 저장된 환경변수들을 사용한 탐색
2) Kubernetes Cluster 내부 DNS를 이용한 Service Discovery
coredns라는 이름으로 작동하고 있는 deployment (이전 버전에서는 kube-dns을 활용했으므로 용어 주의)
SERVICE_NAME.NAMESPACE.k8s_OBJECT.k8s_CLUSTER_DOMAIN
→ myapp-svc-nodeport.default.services.cluster.local
##### core-dns 동작확인 ##### vagrant@kube-control1:~/work/20210831$ kubectl get all -n kube-system -l k8s-app=kube-dns --show-labels NAME READY STATUS RESTARTS AGE LABELS pod/coredns-f9fd979d6-kxj7t 1/1 Running 6 7d19h k8s-app=kube-dns,pod-template-hash=f9fd979d6 pod/coredns-f9fd979d6-tkn6r 1/1 Running 6 7d19h k8s-app=kube-dns,pod-template-hash=f9fd979d6 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d19h k8s-app=kube-dns,kubernetes.io/cluster-service=true,kubernetes.io/name=KubeDNS NAME READY UP-TO-DATE AVAILABLE AGE LABELS deployment.apps/coredns 2/2 2 2 7d19h k8s-app=kube-dns NAME DESIRED CURRENT READY AGE LABELS replicaset.apps/coredns-f9fd979d6 2 2 2 7d19h k8s-app=kube-dns,pod-template-hash=f9fd979d6 ##### FQDN ##### 같은 namespace 내에서 질의시 : myapp-svc-clusterip 다른 namespace 에서 질의시 : myapp-svc-clusterip.default. 오브젝트 타입 지정 : myapp-svc-clusterip.default.svc 전체 FQDN 지정: myapp-svc-clusterip.default.svc.cluster.local vagrant@kube-control1:~$ kubectl run nettool -it --image devops2341/network-multitool:v1 --rm bash bash-5.1# host myapp-svc-clusterip bash-5.1# host myapp-svc-clusterip.default bash-5.1# host myapp-svc-clusterip.default.svc bash-5.1# host myapp-svc-clusterip.default.svc.cluster.local → FQDN myapp-svc-clusterip.default.svc.cluster.local has address 10.100.138.93 |
- Kubernetes Cluster 외부 네트워크
서비스 종류
- Cluster IP
Kubernetes Cluster 내부 서비스를 제공하기 위한 서비스 타입
기본적으로 Kubernetes Cluster 내부에서만 접근할 수 있음
- NodePort
NodePort + ClusterIP
Kubernetes Cluster 의 모든 노드에 외부 접근용 포트를 할당하는 서비스 타입
노드의 Port를 이용하여 외부에서 Kubernetes Cluster에 접근 가능
노드의 Port를 접근하면 Service에 의해 pod로 리다이렉션
pod를 실행하지 않는 노드에도 노드 port가 할당되어 접근 가능
노드의 Port에 할당 가능한 Port 범위 : 30000~32767 범위 (변경가능)
- LoadBalancer
LoadBalancer + NodePort + ClusterIP
NodePort의 확장된 개념이며, 외부의 LoadBalancer를 이용하여 외부에서 접근 가능하도록 하는 서비스 타입
기본적으로 클라우드 서비스 환경에서 지원 On-premise에서는 애드온설치 필요
- ExternalName
Kubernetes Cluster 내부의 pod가 외부의 특정 도메인에 쉽게 접근할 수 있도록 하는 서비스 타입
Kubernetes Cluster 외부의 도메인 주소가 변경되는 경우 해당 주소를 참조하는 컨테이너 이미지 재작성 필요
→ ExternalName 서비스를 사용시, 애플리케이션을 다시 작성할 필요가 없어지게 된다.
<전체실습>
LoadBalancer → NodePort 가 가르키는 Node의 Port → Cluster IP → Pod
LoadBalancer : 현재 on-premise 테스트환경이므로 metallb 애드온을 통해 loadbalancer 서비스 리소스 활용
##### 외부 네트워크에서 접속 테스트를 위한 manifest files 작성 ##### ##### replicaset 생성 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-rs.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp-rs spec: replicas: 3 selector: matchLabels: app: myapp-rs template: metadata: labels: app: myapp-rs spec: containers: - name: myapp image: devops2341/go-myweb:latest ports: - containerPort: 8080 protocol: TCP ##### session affinity 설정 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-ses-aff.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-ses-aff spec: sessionAffinity: ClientIP ports: - port: 80 targetPort: 8080 selector: app: myapp-rs ##### cluster ip 설정 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-clusterip.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-clusterip spec: type: ClusterIP ports: - name: myapp-port port: 80 targetPort: 8080 selector: app: myapp-rs ##### node port 설정 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-nodeport.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-nodeport spec: type: NodePort selector: app: myapp-rs ports: - port: 80 targetPort: 8080 nodePort: 30000 ##### 여기까지 설정 : IP+PORT으로 외부에서 접속 가능 ( control plane, node의 IP + port 30000 )##### ##### loadbalancer 설정 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-lb.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-loadbalancer spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: myapp-rs vagrant@kube-control1:~/work/20210831$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d20h myapp-svc-clusterip ClusterIP 10.100.138.93 <none> 80/TCP 156m myapp-svc-loadbalancer LoadBalancer 10.108.221.7 192.168.200.200 80:30286/TCP 5s myapp-svc-nodeport NodePort 10.97.242.100 <none> 80:30000/TCP 18m myapp-svc-ses-aff ClusterIP 10.102.211.98 <none> 80/TCP 125m test-svc-namedport ClusterIP 10.108.16.205 <none> 80/TCP 102m ##### loadbalancer 서비스에 할당해준 192.168.200.200:80 으로 외부에서 pod까지 접근 가능 ##### + curl 로 테스트 시 : 정상적으로 다른 replica(pod)에 번갈아가면서 요청 확인가능 + 웹브라우저 테스트 시 : 하나의 replica에만 요청 → 웹브라우저 cache때문 + 라운드로빈형태로 lb가 실행되지만, session affinity가 동작중이므로 처음연결된 replica(pod)로 연결 ##### externalname 설정 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-externalname.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-externalname spec: type: ExternalName externalName: www.google.com vagrant@kube-control1:~/work/20210831$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d20h myapp-svc-clusterip ClusterIP 10.100.138.93 <none> 80/TCP 170m myapp-svc-externalname ExternalName <none> www.google.com <none> 5s myapp-svc-loadbalancer LoadBalancer 10.108.221.7 192.168.200.200 80:30286/TCP 14m myapp-svc-nodeport NodePort 10.97.242.100 <none> 80:30000/TCP 33m myapp-svc-ses-aff ClusterIP 10.102.211.98 <none> 80/TCP 139m test-svc-namedport ClusterIP 10.108.16.205 <none> 80/TCP 117m |
- 인그레스 (Ingress)
L7 LoadBalancer 기능을 제공하는 Kubernetes object
NodePort와 LoadBalancer 타입의 서비스가 L4 수준에서 동작하지만, 인그레스는 L7 수준에서 동작
NodePort와 LoadBalancer 타입의 service object는 애플리케이션마다 생성필요.
→ 인그레스는 하나의 리소스만으로 각 애플리케이션에 트래픽 전달이 가능
※ https://kubernetes.github.io/ingress-nginx/deploy/
→ on-premise 환경이므로 bare-metal 배포버전으로 설치
<Ingress nginx Controller 설치> ##### ① Ingress nginx Controller 설치 ##### vagrant@kube-control1:~$ kubectl create -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml → 1.00 릴리즈 버전으로 에러 발생 → 0.47로 진행 ##### ② ingress nginx Controller : running 상태 확인 ##### vagrant@kube-control1:~$ kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-d6wds 0/1 Completed 0 12m ingress-nginx-admission-patch-jnhxp 0/1 Completed 0 12m ingress-nginx-controller-6cb6fdd64b-kcr8l 1/1 Running 0 12m ##### ③ 서비스 manifests 편집 ##### vagrant@kube-control1:~$ kubectl edit services -n ingress-nginx ingress-nginx-controller spec: Cluster IP externalIPs: - 192.168.200.21 → 각 노드들의 ip 입력 - 192.168.200.22 - 192.168.200.23 externalTrafficpolicy : Cluster service/ingress-nginx-controller edited ##### ④ 서비스 수정결과 확인 : ingress 설치완료 ##### vagrant@kube-control1:~$ kubectl get services -n ingress-nginx (수정전) NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.108.206.128 <none> 80:31006/TCP,443:31890/TCP 7m6s ingress-nginx-controller-admission ClusterIP 10.109.80.0 <none> 443/TCP 7m6s vagrant@kube-control1:~$ kubectl get services -n ingress-nginx (수정후) NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.108.206.128 192.168.200.21,192.168.200.22,192.168.200.23 80:31006/TCP,443:31890/TCP 10m ingress-nginx-controller-admission ClusterIP 10.109.80.0 <none> 443/TCP 10m ##### ⑤ ingress서비스를 실행할 앱,노드포트,ingress manifests 작성/실행 ##### vagrant@kube-control1:~$ cat myapp-rs.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp-rs spec: replicas: 3 selector: matchLabels: app: myapp-rs template: metadata: labels: app: myapp-rs spec: containers: - name: myapp image: devops2341/go-myweb:latest ports: - containerPort: 8080 protocol: TCP vagrant@kube-control1:~$ cat myapp-np.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-np spec: type: NodePort ports: - port: 80 targetPort: 8080 nodePort: 31111 selector: app: myapp-rs vagrant@kube-control1:~$ cat myapp-ing.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: myapp-ing spec: rules: - host: myapp.example.com http: paths: - path: / backend: serviceName: myapp-svc-np servicePort: 80 vagrant@kube-control1:~$ kubectl create -f myapp-rs.yaml replicaset.apps/myapp-rs created vagrant@kube-control1:~$ kubectl create -f myapp-np.yaml service/myapp-svc-np created vagrant@kube-control1:~$ kubectl create -f myapp-ing.yaml Warning:networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.networking.k8s.io/myapp-ing created ##### ⑥ 설정적용 확인 ##### vagrant@kube-control1:~$ kubectl get pods,deployments,replicasets -n ingress-nginx NAME READY STATUS RESTARTS AGE pod/ingress-nginx-admission-create-d6wds 0/1 Completed 0 31m pod/ingress-nginx-admission-patch-jnhxp 0/1 Completed 0 31m pod/ingress-nginx-controller-6cb6fdd64b-kcr8l 1/1 Running 0 31m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/ingress-nginx-controller 1/1 1 1 31m NAME DESIRED CURRENT READY AGE replicaset.apps/ingress-nginx-controller-6cb6fdd64b 1 1 1 31m vagrant@kube-control1:~$ kubectl get pods,deployments,replicasets -n default NAME READY STATUS RESTARTS AGE pod/myapp-rs-54fks 1/1 Running 0 2m10s pod/myapp-rs-8g9wk 1/1 Running 0 2m10s pod/myapp-rs-txjm6 1/1 Running 0 2m10s NAME DESIRED CURRENT READY AGE replicaset.apps/myapp-rs 3 3 3 2m10s vagrant@kube-control1:~$ kubectl describe ingress Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress Name: myapp-ing Namespace: default Address: 192.168.200.22 Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- myapp.example.com / myapp-svc-np:80 (192.168.119.148:8080,192.168.233.227:8080,192.168.9.108:8080) Annotations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 2m22s (x2 over 2m58s) nginx-ingress-controller Scheduled for sync vagrant@kube-control1:~$ kubectl get ingresses Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE myapp-ing <none> myapp.example.com 192.168.200.22 80 3m16s ##### ⑦ 테스트 ##### vagrant@kube-control1:~$ curl --resolve myapp.example.com:80:192.168.200.22 Hello World! myapp-rs-54fks vagrant@kube-control1:~$ curl --resolve myapp.example.com:80:192.168.200.22 http://myapp.example.com/\?det ail\=header Hello World! myapp-rs-8g9wk [Request Headers] GET /?detail=header HTTP/1.1 X-Forwarded-For: [10.0.2.15] X-Forwarded-Host: [myapp.example.com] X-Forwarded-Port: [80] X-Forwarded-Proto: [http] User-Agent: [curl/7.68.0] Accept: [*/*] X-Request-Id: [6ba116ca538f9a3a1ad81f8828c21c8f] X-Real-Ip: [10.0.2.15] X-Scheme: [http] ※ 실제 존재하지 않는 도메인이므로 control plane의 /etc/hosts 편집 192.168.200.22 myapp.example.com → 줄 추가 저장후 curl 명령으로 테스트시 hosts 파일을 우선하여 탐색하므로 확인가능 vagrant@kube-control1:~$ curl http://myapp.example.com Hello World! myapp-rs-txjm6 |
---
- Headless
서비스의 ClusterIP가 아닌 개별 pod로 직접 접근할 필요가 있는 경우에 사용하는 서비스 타입
service가 ip를 갖지 않는다.
##### headless manifests 작성 ##### vagrant@kube-control1:~/work/20210831$ cat myapp-svc-headless.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc-headless spec: clusterIP: None ports: - port: 80 targetPort: 8080 selector: app: myapp-rs-headless vagrant@kube-control1:~/work/20210831$ cat myapp-rc-headless.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp-rs-headless spec: replicas: 3 selector: matchLabels: app: myapp-rs-headless template: metadata: labels: app: myapp-rs-headless spec: containers: - name: myapp image: devops2341/go-myweb:latest ports: - containerPort: 8080 protocol: TCP ##### headless manifests 실행 ##### vagrant@kube-control1:~/work/20210831$ kubectl create -f myapp-rc-headless.yaml replicaset.apps/myapp-rs-headless created vagrant@kube-control1:~/work/20210831$ kubectl create -f myapp-svc-headless.yaml service/myapp-svc-headless created ##### 확인 ##### vagrant@kube-control1:~/work/20210831$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d myapp-svc-headless ClusterIP None <none> 80/TCP 6s → cluster ip가 할당되지 않음 vagrant@kube-control1:~/work/20210831$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-rs-headless-5ms8f 1/1 Running 0 34s myapp-rs-headless-66fwt 1/1 Running 0 34s myapp-rs-headless-j9dwd 1/1 Running 0 34s vagrant@kube-control1:~/work/20210831$ kubectl get replicasets NAME DESIRED CURRENT READY AGE myapp-rs-headless 3 3 3 46s vagrant@kube-control1:~/work/20210831$ kubectl get endpoints myapp-svc-headless NAME ENDPOINTS AGE myapp-svc-headless 192.168.119.144:8080,192.168.233.218:8080,192.168.9.107:8080 81s → endpoint : pods의 ip vagrant@kube-control1:~/work/20210831$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-rs-headless-5ms8f 1/1 Running 0 104s 192.168.9.107 kube-node1 <none> <none> myapp-rs-headless-66fwt 1/1 Running 0 104s 192.168.233.218 kube-node2 <none> <none> myapp-rs-headless-j9dwd 1/1 Running 0 104s 192.168.119.144 kube-node3 <none> <none> ##### headless manifests 작성##### vagrant@kube-control1:~$ kubectl run nettool -it --image devops2341/network-multitool:v1 --rm bash bash-5.1# curl http://192.168.9.107:8080 Hello World! myapp-rs-headless-5ms8f bash-5.1# host myapp-svc-headless myapp-svc-headless.default.svc.cluster.local has address 192.168.9.107 myapp-svc-headless.default.svc.cluster.local has address 192.168.119.144 myapp-svc-headless.default.svc.cluster.local has address 192.168.233.218 |
'kubernetes' 카테고리의 다른 글
20210902 (목) kubernetes Persistent Volume, 정적 동적 volume provisioning (0) | 2021.09.02 |
---|---|
20210901 (수) kubernetes ingress, volume (0) | 2021.09.01 |
20210830 (월) service의 종류 (0) | 2021.08.30 |
20210827 (금) 컨트롤러 활용 (0) | 2021.08.27 |
20210826 (목) 교재 제공 예제파일 활용 - git (0) | 2021.08.26 |