Kubernetes Network [ ClusterIP, NodePort ]
Kubernetes Network 관련 글 이동
1. Kuberentes Network 이론
2. Kubernetes Network (ClusterIP, NodePort)
3. Kubernetes Network (LoadBalancer)
4. Kubernetes Network (Ingress)
참고) 실습환경
[Master Node server]
OS = CentOS 7
IP : 192.168.64.150
리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64
docker version : 1.13.1
docker api verison : 1.26
[Worker Node server]
OS = CentOS 7
IP : 192.168.64.149
리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64
docker version : 1.13.1
docker api verison : 1.26
[Kubernetes version]
1.18
[예제 환경]
Pod 1
Tomcat Container 1개 포함
Service 1
외부 네트워크에서
"Pod 1"에 접근하기 위한
NodPort Type Service
Pod 2
Mysql Container 1개 포함
Service 2
Pod1에서 "Pod 2"에 접근하기 위한
ClusterIP Type Service
1. Tomcat Pod 생성
(컨테이너 이미지 참고)
docker 실습과정에서 사용했던 image를
docker hub 에 push 해놨음
이미지 경로
- Tomcat = peksoon/tomcat:1.0.0
- mysql = peksoon/mysql:1.0.0
1.1. Pod 생성
1.1.1. yaml 파일 작성
[pod_test1.yaml 파일 생성]
apiVersion: v1 kind: Pod metadata: name: iksoon-pod-tomcat labels: app: tomcat8 spec: containers: - name: iksoon-tomcat-test image: peksoon/tomcat:1.0.0 ports: - containerPort: 8080 nodeSelector: kubernetes.io/hostname: kube.worker.node |
[yaml 파일 작성법]
주의)
yaml 에서는 들어 쓰기가 중요함 작성 시 주의
( : ) 뒤에는 한칸 띄워 줘야 함
yaml 파일 확장자
yaml or yml
공식 사이트는 yaml 확장자를 권장
apiVersion: v1
k8s API 버전 명세
kind: Pod
생성한 k8s 리소스 타임
Pod를 정의함
metadata:
Pod의 name과 labe을 정함
metadata.name :
생성할 pod의 이름 iksoon-pod-tomcat으로 정함
동일한 namespace 상에서 유일한 이름을 가져야 함
metadata.label :
app:tomcat8으로 정함
레이블 은 파드와 같은 오브젝트에 첨부된 키와 값의 쌍
오브젝트마다 키와 값으로 레이블을 정의할 수 있음
오브젝트의 키는 고유한 값이어야 함
spec :
생성할 pod의 구체적인 내용을 정의
spec.containers :
pod는 1개 이상의 container를 포함해야 함
해당 containers에 원하는 만큼의 container를 정의해 넣으면 됨
상위에서는 하나의 container 만 정의함
spec.-name:
동일한 pod 내에서 유일한 이름을 가져야 함
spec.image:
docker image 경로
docker images는 docker registry에서 pull로 받아오는데
docker registry 가 명시되어 있지 않다면
docker 공식 public registry 인 docker hub에서 해당 image를 가져옴
상위는 이전 실험에서 생성했던 image를 docker hub에 올려놓아서
상위와 같이 사용함
spec.ports.containerPort:
pod 내부 컨테이너 port를 설정
현재 tomcat8에 8080으로 접근해야 하니 8080으로 설정함
spec.nodeSelector :
주의)
실제 kubernetes 사용 시 nodeSelector 옵션은 사용하지 않는 것이 좋음
kubernetes 가 자동으로 여유 있는 worker node에 pod 들을 할당하기 때문.
현재는 이런 기능도 있다.... 라는걸 보여주기 위해 사용해봄
실행될 Worker Node를 지정하는 옵션
nodeSelector와 key, value를 지정하면 해당 label을 갖고 있는 node에만 배포가 진행
nodecSelector를 설정하지 않으면 kubernetes 가 자동으로 할당함
위 예시는
kube.worker.node Node에만 할당하기 위해
hostname으로 명시함
(설정법)
1.) 명령어 : kubectl get nodes
node 목록을 확인함
2.) kubectl describe node "노드 이름"
원하는 노드의 label 정보를 확인함
3.) 매칭 되는 label을 정해서 nodeSelector에서 설정함
4.) 참고
선택한 노드에 레이블을 추가하는 명령어 : kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>
예) kubectl label nodes kube.worker.node app=testinsert
1.1.2. pod 오브젝트 생성 (apply, create)
kubectl을 사용해서 pod, service, controller 등 yaml or json 파일을 사용해서
각종 object를 생성하는 방법으로는 create와 apply 2가지 명령이 있음
1.1.2.1. create와 apply 명령의 차이점
apply
Imperative Management
디렉터리 대상 : 디렉터리에 포함된 모든 yaml파일 설정을 한 번에 생성 가능
과거 설정에 대한 log를 가지고 있음
기존의 run 중인 object와 동일한 object를 생성 시
해당 object 내용 update
create
Declarative Management
파일 대상 : 한 번에 한 가지의 yaml 파일 설정 생성 가능
과거 설정에 대한 log를 생성하지 않음
기존의 run 중인 object와 동일한 object를 생성 시
AlreadyExists 발생하며 생성 오류
즉 오로지 새로운 object 만 생성 가능
주로 yaml 파일을 사용하지 않고 명령어로 object를 생성할 시 사용함
참고
create -f 로 하면 이후에 apply를 통해 다시 반영할 수 없음
그러나 처음부터 apply -f 로 하면 계속 apply 가능
결론 : apply 명령을 사용하면 됨
명령어
kubectl apply -f pod_test1.yaml
1.1.3. Pod 생성 배포 결과 확인
명령어
kubectl get pods
kubectl get pods -o wide
확인
생성된 Pod의 STATUS가 Running 상태면 정상.
1.1.4. Pod의 container 안으로 ssh 접속
명령어
pod 안에 컨테이너가 1개일 경우 : kubectl exec [ pod 명 ] -it -- /bin/bash
예) kubectl exec -it iksoon-pod-tomcat -- /bin/bash
컨테이너가 다수일 경우 : kubectl exec [ pod 명 ] -c [ Container 명 ] -it -- bash
예) kubectl exec iksoon-pod-tomcat -c iksoon-tomcat-test -it -- /bin/bash
컨테이너에서 나오기 단축키
ctrl + p
ctrl + q
1.1.5. 해당 pod 가 어떤 worker node에서 실행 중 인지 확인하는 명령
명령어
kubectl get pods -o wide
1.1.6. 생성한 Pod에 대한 자세한 정보
명령어 : kubectl describe pod <pod name >
예) kubectl describe pod iksoon-pod-tomcat
1.1.7. 완료
이 단계 까지가 Pod를 생성한 상태임
하지만 아직 접속은 불가능함
Pod 안의 tomcat8에 접근하기 위해서는
Service Object를 생성해서
네트워크를 연결해줘야 함
1.1.8. (참고) pod 삭제 명령어 참고
kubectl delete -f ./pod.json
pod.json에 지정된 유형 및 이름을 사용하여 파드 삭제
kubectl delete pod,service baz foo
"baz", "foo"와 동일한 이름을 가진 파드와 서비스 삭제
kubectl delete pods,services -l name=myLabel
name=myLabel 라벨을 가진 파드와 서비스 삭제
kubectl delete pods,services -l name=myLabel --include-uninitialized
초기화되지 않은 것을 포함하여, name=myLabel 라벨을 가진 파드와 서비스 삭제
kubectl -n my-ns delete pod,svc --all
초기화되지 않은 것을 포함하여, my-ns 네임스페이스 내 모든 파드와 서비스 삭제
예)
kubectl delete -f pod_test.yaml
kubectl delete pod pod-test1
2. Tomcat Service 생성
참고그림
참고) IP대역은 실습환경과 동일하지 않음
2.1. Kubernetes Serivces 개념
Pod을 외부 네트워크와 연결해주고 여러 개의 Pod을 바라보는 내부 로드 밸런서를 생성할 때 사용
쿠버네티스 클러스터안에 컨트롤러를 이용해서 포드를 띄웠다면 이제 그 포드들에 접근하는 방법에 대해 알아봐야 함
포드는 컨트롤러에 의해 관리되기 때문에 한 곳에 고정돼서 떠 있지 않고,
클러스터 내를 옮겨 다니게 됨
이 과정에서 노드를 옮기면서 실행되기도 하고 클러스터 내의 포드 IP가 변경되기도 함
이렇게 동적으로 변하는 포드들에 고정된 방법으로 접근하기 위해서 사용하게는 쿠버네티스의 서비스(Service) 임
서비스를 사용하게 되면 포드가 클러스터 내의 어디에 있는지에 상관없이 고정된 주소를 이용해서 접근이 가능
2.2. Service 생성
2.2.1. yaml 파일 작성
외부 네트워크에 있는 사용자가 Tomcat Container가 있는 Pod에 접근하기 위해 NodePort Type의 Service Object를 생성
[service_tomcat_test1.yaml 파일 생성]
apiVersion: v1 kind: Service metadata: name: service-iksoon-tomcat labels: name: service-tomcat spec: type: NodePort ports: - name: "iksoon-tomcat8-network-setting" port: 8088 # Service 자신의 포트 targetPort: 8080 # pod 내 컨테이너 포트 nodePort: 30001 selector: # 뒷단의 pod와 연계 app: tomcat8 |
[작성법]
주의)
yaml에서는 들어 쓰기가 중요함 작성 시 주의
yaml 파일 확장자
yaml or yml
공식 사이트는 yaml 확장자를 권장
apiVersion: v1
k8s API 버전 명세
kind: Service
생성한 k8s 리소스 타임
Service를 정의함
metadata:
Service의 name 과 labe을 정함
metadata.name :
생성할 Service 의 이름 service-iksoon-tomcat으로 정함
동일한 namespace 상에서 유일한 이름을 가져야 함
metadata.label :
name: service-tomcat
spec :
생성할 pod의 구체적인 내용을 정의
spec.type :
type으로 서비스 타입을 지정
spec.type을 지정하지 않으면 기본 타입은 ClusterIP
위에서는 외부에서 tomcat으로 접속해야 하니
NodePort Type을 사용함
spec.ports:
Cluster 내부에서 사용될 Service object의 포트
spec.ports는 배열 형태의 값임.
서비스가 포트를 외부에 제공할 때 하나가 아니라 여러 개를 한꺼번에 제공 가능한데
spec.ports 하위에 값을 넣어주면 됨
spec.ports.port: 8088
Service 자신의 포트로
service에 접근하기 위해서는 해당 port를 사용해야 함
spec.ports.targetPort: 8080
Service object로 들어온 요청을 전달할 target이 되는 Pod이 노출하고 있는 포트
pod 내의 컨테이너에 접근하기 위한 포트
현재 상위에서 생성한 pod는 내부에 tomcat container 가 존재하는데
해당 tomcat 이 8080 port를 사용하므로
8080 port로 설정함
기본적으로 targetPort는 port 필드와 동일한 값으로 설정
하지만 실험 중에는 구분되는 것을 확인하기 위해 다르게 설정
spec.ports.nodePort: 30001
node에 어떤 포트를 열어줄지 지정하는 설정
nodePort를 지정하지 않으면 kubernetes 가 임의로 포트를 선택함
즉 외부에서 접근하기 위한 port
외부 다른 서버에서 현재 kubernetes 서버의 ip와
nodePort로 설정된 port를 입력하면
pod의 container까지 접속이 가능해짐
(notePort 제약사항)
포트당 한 서비스만 할당 가능
30000 ~ 32767 사이의 포트만 사용 가능
Node 나 VM의 IP 주소가 바뀌면 이를 반영해야 함
spec.selector :
Service object가 요청을 전달할 Pod을 찾기 위한 검색어
Pod의 label이 app: tomcat8 인 Pod을 찾아 요청을 전달하게 됨
서비스와 연결할 포드에 지정된 라벨
상위 pod yaml 파일에서 지정한 포드 라벨이
app: tomcat8 이므로
app: tomcat8으로 설정
참고)
찾은 Pod이 여러 개인 경우 load balancing 정책에 따라 하나의 Pod을 선택함
2.2.2. Service Object 생성
명령어 :
kubectl apply -f service.yaml
2.2.3. Service 생성 배포 결과 확인
명령어 :
kubectl get service
kubectl get service -o wide
2.2.4. 완료
이 단계 까지가 Service를 생성한 상태임
페이지 접속 방법 :
Pod 가 있는 Worker Node or Master Node Server의 IP
service에서 설정한 nodePort: 30001 번호로 접속
예) http://192.168.64.149:30001/iksoon_test/iksoon_home.jsp
2.2.5. (참고) Service 삭제 명령어
명령어 : kubectl delete services my-service
예) kubectl delete services service-iksoon-tomcat
3. MySQL Pod 생성
컨테이너 이미지 참고
docker 실습과정에서 사용했던 image를
docker hub에 push 해놨음
이미지 경로
- MySQL = peksoon/mysql:1.0.0
3.1. Pod 생성
3.1.1. yaml 파일 작성
[pod_mysql.yaml 파일 생성]
apiVersion: v1 kind: Pod metadata: name: iksoon-pod-mysql labels: app: mysql spec: containers: - name: iksoon-mysql-test image: peksoon/mysql:1.0.0 ports: - containerPort: 3306 nodeSelector: kubernetes.io/hostname: kube.worker.node |
3.1.2. pod 오브젝트 생성 (apply, create)
명령어 : kubectl apply -f pod_mysql.yaml
3.1.3. Pod 생성 배포 결과 확인
명령어 :
kubectl get pods
kubectl get pods -o wide
ContainerCreating 상태에서 일정 시간이 지난 후 Runngin 상태로 변경되는 것을 확인할 수 있음
3.1.4. Pod의 container 안으로 ssh 접속
명령어 : kubectl exec iksoon-pod-mysql -c iksoon-mysql-test -it -- /bin/bash
mysql login 후 DB와 Table 정보를 생성해야 함
명령어 실행 :
create database dockerdb; create table test(name varchar(10), testdata varchar(50) ); insert into test values('iksoon', 'docker example test'); |
컨테이너에서 나오기 단축키
ctrl + p
ctrl + q
4. Mysql Service 생성
4.1. Service 생성
참고그림
참고) IP대역이 실습환경과 동일하지 않음
4.1.1. yaml 파일 작성
Tomcat Container가 있는 Pod에서 MySQL Container가 있는 Pod에 접근하기 위해
ClusterIP Type의 Service Object를 생성
service_mysql.yaml 파일 생성
apiVersion: v1 kind: Service metadata: name: service-iksoon-mysql labels: name: service-mysql spec: type: ClusterIP ports: - name: "iksoon-mysql-network-setting" port: 4406 # Service 자신의 포트 targetPort: 3306 # pod 내 컨테이너 포트 selector: # 뒷단의 pod와 연계 app: mysql |
4.1.2. Service Object 생성
명령어 : kubectl apply -f service.yaml
4.1.3. Service 생성 배포 결과 확인
명령어 :
kubectl get service
kubectl get service -o wide
Cluster IP를 확인할 수 있음
mysql service cluster IP = 10.103.79.132
4.1.4. 완료
이 단계 까지가 Cluster IP Service를 생성한 상태임
Tomcat Container 가 있는 pod에서
Mysql Container 가 있는 Pod로 연결하기 위해서는
Cluster IP로 붙어야 함
참고)
Cluster IP의 경우 갱신되는 경우가 많음
IP를 사용하지 않고 도메인을 사용하는 방법이 있음
String DB_URL = "jdbc:mysql://iksoon-mysql-service.default.svc.cluster.local:3306/testdb";
도메인 설명 : [서비스 명].[네임스페이스명].svc.cluster.local
접속 결과
자주 쓰는 명령어 참고
yaml 파일 적용
kubectl apply -f peksoon_deployment.yaml
deployment 상태 확인
kubectl describe deployment
deployment의 replicaset으로 생성된 pod 수 , ip확인
kubectl get pods -o wide
생성된 모든 정보 확인
kubectl get all
service에 대한 자세한 정보
(Endpoints 항목을 보면 replicaset으로 생성된 pod 수만큼 ip가 할당됨을 확인할 수 있음
kubectl describe service
생성된 pod의 container 안으로 접속
kubectl exec [pod 이름] -c [container 이름] -it -- /bin/bash
kubectl exec iksoon-deployment-6b9d655f64-x7znk -c iksoon-tomcat -it -- /bin/bash
deployment 이미지 업데이트
yaml 파일 수정 후 다시 apply
kubectl apply -f peksoon_deployment.yaml
생성된 모든 정보 확인
kubectl get all
확인하면 실시간으로 pod 가 변경되는 것을 확인할 수 있음
(참고) 다양한 종류의 Deployment 예제 yaml
예제 1)
1개의 deployment
1개의 pod 안에
2개의 container
사용한 yaml 파일 예시
apiVersion: apps/v1 kind: Deployment metadata: name: iksoon-deployment labels: app: iksoon-test spec: replicas: 3 selector: matchLabels: app: iksoon-pod template: metadata: labels: app: iksoon-pod spec: containers: - name: iksoon-tomcat image: peksoon/iksoon_tomcat:1.0.3 ports: - containerPort: 8080 - name: iksoon-mysql image: peksoon/iksoon_mysql:1.0.2 ports: - containerPort: 3306 --- apiVersion: v1 kind: Service metadata: name: iksoon-tomcat-service labels: name: service-tomcat spec: type: NodePort ports: - name: "iksoon-tomcat8-network-setting" port: 8088 # Service 자신의 포트 targetPort: 8080 # pod 내 컨테이너 포트 nodePort: 30001 selector: # 뒷단의 pod와 연계 app: iksoon-pod |
참고)
tomcat에서 mysql 통신 시
같은 pod 안에 있음으로 localhost:3306으로 통신이 가능함
mysql의 경우 아래 쿼리를 등록해줘야 정상 동작함
create database testdb; use testdb; create table test(name varchar(10), testdata varchar(50) ); insert into test values('iksoon', 'docker example test'); |
예제 2)
1개의 deployment
1개의 pod 안에
1개의 container tomcat
,
1개의 pod 안에
1개의 container mysql
사용한 yaml 파일 예시
apiVersion: apps/v1 kind: Deployment metadata: name: iksoon-deployment labels: app: iksoon-tomcat spec: replicas: 3 selector: matchLabels: app: iksoon-pod-tomcat template: metadata: labels: app: iksoon-pod-tomcat spec: containers: - name: iksoon-tomcat image: peksoon/iksoon_tomcat:1.0.1 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: iksoon-tomcat-service labels: name: service-tomcat spec: type: NodePort ports: - name: "iksoon-tomcat8-network-setting" port: 8088 # Service 자신의 포트 targetPort: 8080 # pod 내 컨테이너 포트 selector: # 뒷단의 pod와 연계 app: iksoon-pod-tomcat --- apiVersion: v1 kind: Pod metadata: name: iksoon-pod-mysql labels: app: iksoon-mysql spec: containers: - name: iksoon-mysql-test image: peksoon/iksoon_mysql:1.0.1 ports: - containerPort: 3306 --- apiVersion: v1 kind: Service metadata: name: service-iksoon-mysql labels: name: service-mysql spec: type: ClusterIP ports: - name: "iksoon-mysql-network-setting" port: 4406 # Service 자신의 포트 targetPort: 3306 # pod 내 컨테이너 포트 selector: # 뒷단의 pod 와 연계 app: iksoon-mysql |
예제 3)
1개의 pod 안에
1개의 container tomcat
,
1개의 pod 안에
1개의 container mysql
tomcat = NodePort
mysql = ClusterIP
사용한 yaml파일 예시
apiVersion: v1 kind: Pod metadata: name: iksoon-pod-tomcat labels: app: tomcat8 spec: containers: - name: iksoon-tomcat-test image: peksoon/tomcat:1.0.0 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: service-iksoon-tomcat labels: name: service-tomcat spec: type: NodePort ports: - name: "iksoon-tomcat8-network-setting" port: 8088 # Service 자신의 포트 targetPort: 8080 # pod 내 컨테이너 포트 nodePort: 30001 selector: # 뒷단의 pod와 연계 app: tomcat8 --- apiVersion: v1 kind: Pod metadata: name: iksoon-pod-mysql labels: app: mysql spec: containers: - name: iksoon-mysql-test image: peksoon/mysql:1.0.0 ports: - containerPort: 3306 --- apiVersion: v1 kind: Service metadata: name: service-iksoon-mysql labels: name: service-mysql spec: type: ClusterIP ports: - name: "iksoon-mysql-network-setting" port: 4406 # Service 자신의 포트 targetPort: 3306 # pod 내 컨테이너 포트 selector: # 뒷단의 pod 와 연계 app: mysql |
예제 4)
1개의 pod 안에
2개의 container tomcat, mysql
emptyDir Volume 설정
사용한 yaml 파일 예시
apiVersion: v1 kind: Pod metadata: name: shared-volumes-pod spec: containers: - name: iksoon-mysql-test image: peksoon/mysql:1.0.0 volumeMounts: - name: shared-storage mountPath: /data/shared - name: iksoon-tomcat-test image: peksoon/tomcat:1.0.0 volumeMounts: - name: shared-storage mountPath: /data/shared volumes: - name : shared-storage emptyDir: {} |
제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!
참고
실습 따라 하기 (정확히 6강부터 Kubernetes 강의임)
https://www.youtube.com/watch?v=xZ3tcFvbUGc
pod 생성
tomcat pod 생성
https://kubernetes.io/ko/docs/tutorials/stateless-application/expose-external-ip-address/
kubernetes 각종 조회 명령어 참고
https://kubernetes.io/ko/docs/reference/kubectl/cheatsheet/
service object 설명
https://waspro.tistory.com/520
https://cloud.google.com/kubernetes-engine/docs/how-to/exposing-apps?hl=ko
service 생성 시 kubernetes domain 생성 설명
https://arisu1000.tistory.com/27859
소스 참고
https://github.com/subicura/workshop-k8s-basic
'Kubernetes > 네트워크' 카테고리의 다른 글
Pod의 veth (Virtual Ethernet Interface) 장치 찾기 (0) | 2020.11.07 |
---|---|
Kubernetes Network Policy (0) | 2020.11.07 |
Kubernetes Network (Ingress) (2) | 2020.08.12 |
Kubernetes Network (LoadBalancer) (3) | 2020.08.09 |
Kuberentes Network 이론 (2) | 2020.08.09 |