# Ingress
* 앞서 실습한 Loadbalancer는 NLB
- Ingress는 L7의 Loadbalancer 역할을 할 수 있다.
- Ingress가 들어온 경로를 인지하고 service로 트래픽을 라우팅한다.
# git clone https://github.com/hali-linux/_Book_k8sInfra.git
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.2/ingress-nginx.yaml
# kubectl get pods -n ingress-nginx
# mkdir ingress && cd $_
- yum install git으로 git 설치 후 ingress 야믈 파일 어플라이
- ingress 설치
## Ingress 아키텍처
- clusterIP
- Deployment pod
## Docker VM에서 사설 레지스트리로 이미지 빌드 후 푸시
- vi /etc/docker/daemon.json 경로에 사설 레지스트리 주소 넣어주기
- test-home 경로에 images 폴더와 index.html 위치시키기
*** FOOD
# tar cvf food.tar images index.html
# vi Dockerfile
FROM nginx:latest
ADD food.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
- tar 파일로 images와 index.html을 묶기
*** index.html
- background: blue
- food
- Dockerfile을 수정
docker build -t 192.168.1.148:5000/test-home:v1.0 .
docker push 192.168.1.148:5000/test-home:v1.0
- 이미지 빌드 후 push
*** SALES
# tar cvf sale.tar images index.html
# vi Dockerfile
FROM nginx:latest
ADD sale.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
*** index.html
- background: green
- sales
- Dockerfile을 수정
docker build -t 192.168.1.148:5000/test-home:v2.0 .
docker push 192.168.1.148:5000/test-home:v2.0
- 이미지 빌드 후 push
*** HOME
# tar cvf home.tar images index.html
# vi Dockerfile
FROM nginx:latest
ADD home.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
*** index.html
- backgorund: pink
- home
- Dockerfile 수정
docker build -t 192.168.1.148:5000/test-home:v0.0 .
docker push 192.168.1.148:5000/test-home:v0.0
- 이미지 빌드 후 push
## Deployment
- master1으로 이동 후 진행
# vi ingress-deploy.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: foods-deploy
spec:
replicas: 1
selector:
matchLabels:
app: foods-deploy
template:
metadata:
labels:
app: foods-deploy
spec:
containers:
- name: foods-deploy
image: 192.168.1.148:5000/test-home:v1.0
---
apiVersion: v1
kind: Service
metadata:
name: foods-svc
spec:
type: ClusterIP
selector:
app: foods-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sales-deploy
spec:
replicas: 1
selector:
matchLabels:
app: sales-deploy
template:
metadata:
labels:
app: sales-deploy
spec:
containers:
- name: sales-deploy
image: 192.168.1.148:5000/test-home:v2.0
---
apiVersion: v1
kind: Service
metadata:
name: sales-svc
spec:
type: ClusterIP
selector:
app: sales-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: home-deploy
spec:
replicas: 1
selector:
matchLabels:
app: home-deploy
template:
metadata:
labels:
app: home-deploy
spec:
containers:
- name: home-deploy
image: 192.168.1.148:5000/test-home:v0.0
---
apiVersion: v1
kind: Service
metadata:
name: home-svc
spec:
type: ClusterIP
selector:
app: home-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl apply -f ingress-deploy.yaml
- apply
- pod와 clusterip 서비스가 생성된다
- 지금까지 Deployment와 총 3개 (food, sale, home) clusterIP 서비스와 파드를 만들었다.
## Ingress - config
- Ingress 생성
# vi ingress-config.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /foods
backend:
serviceName: foods-svc
servicePort: 80
- path: /sales
backend:
serviceName: sales-svc
servicePort: 80
- path:
backend:
serviceName: home-svc
servicePort: 80
kubectl apply -f ingress-config.yaml
get ingress ingress-nginx
kubectl describe ingress ingress-nginx
- rules에 경로 기반 라우팅 생성
## Ingress - service(Controller)
# vi ingress-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller # controller 자체가 pod고 이 pod는 Ingress의 rule을 보고 있다.
namespace: ingress-nginx
spec:
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
selector:
app.kubernetes.io/name: ingress-nginx # annotation지정으로 만들어진 컨트롤러 역할을하는 nginx pod에 연결
type: LoadBalancer
externalIPs:
- 192.168.2.105
kubectl apply -f ingress-service.yaml
- 지금까지의 작업
- 경로 기반 라우팅 확인
## Metallb(dhcp의 기능)
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
# kubectl get pods -n metallb-system -o wide
- Metallb 설치
# vi metallb-l2config.yaml
apiVersion: v1
kind: ConfigMap # 환경설정과 같은 외부의 변수들을 정해 놓고 참조하는 자원
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: nginx-ip-range
protocol: layer2
addresses:
- 192.168.2.96-192.168.2.97
# kubectl apply -f metallb-l2config.yaml
# kubectl describe configmaps -n metallb-system
- ConfigMap 생성
# vi metallb-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod-container
image: 192.168.1.148:5000/nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-pod
spec:
type: LoadBalancer
# externalIPs: # 외부 아이피 자동 할당
# -
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
# kubectl apply -f metallb-test.yaml
- Pod 생성
kubectl delete -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
- metallb 지우기
## metlalb 수정
- 할당할 수 있는 외부 IP를 고정한다
- vi metallb-l2config.yaml
# vi metallb-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod-container
image: 192.168.1.148:5000/nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-pod
spec:
type: LoadBalancer
# externalIPs: # 외부 아이피 자동 할당
# -
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
- 서비스와 pod 생성
cp metallb-test.yaml metallb-test1.yaml
- metallb-test1.yaml 파일 생성 후 수정
# kubectl apply -f metallb-test.yaml
# kubectl apply -f metallb-test1.yaml
- apply
- get service에서 외부 IP 할당 확인
# Volume
- Pod가 지워져도 볼륨은 지워지지 않도록 Persistent Volume 생성
* PV: pod 바깥에 있는 저장 공간
* PVC : PV에 얼만큼의 공간을 이용할 것인지 요청
* PV의 공간은 로컬의 공간일 수도 있고, 네트워크 공간(nfs)일 수도 있다.
* 컨테이너 외부(local)에 있는 볼륨에 PV공간을 생성 후 PVC로 공간 할당 요청
* worker노드에 pv가 생성
## yaml파일 생성
# vi pv-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Mi # 가상 실습환경에서는 큰 의미가 없다. 퍼블릭클라우드에서는 의미 O
accessModes:
- ReadWriteOnce # ReadWriteMany, ReadOnlyMany(접근 보안)
hostPath:
path: "/mnt/data" # worker노드의 경로. worker노드에 자동으로 생성됨.(1 or 2)
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
selector:
matchLabels:
type: local
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
labels:
app: task-pv-pod
spec:
volumes:
- name: task-pv-storage # 볼륨의 이름(pv)
persistentVolumeClaim:
claimName: task-pv-claim # PVC의 이름
containers:
- name: task-pv-container
image: 192.168.1.148:5000/nginx:latest
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html" # 마운트 경로
name: task-pv-storage # 마운트할 볼륨
# rm -rf /mnt/data:
# kubectl apply -f pv-pvc-pod.yaml
# mkdir /mnt/data
# vi /mnt/data/index.html # 경로 생성
# echo "HELLO" > /mnt/data/index.html
# kubectl delete pod task-pv-pod # pod 삭제
# kubectl delete pvc task-pv-claim # pvc 삭제; pod와 pvc를 지워도 pv는 남아있다.(persistent)
# Retain 동일한 스토리지 자산을 재사용하려는 경우, 동일한 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다.
- pod 생성 확인
- pod의 라벨 확인
- loadbalancer 서비스가 pv 파드를 가리키도록 만든다.
- 서비스 확인
- mnt/data/index.html 경로를 생성하지 않으면 403 Forbidden 페이지가 나온다.
- 마운트가 잘되어 있음을 반증
- 마운트가 되면 /mnt/data 폴더 안에 아무 것도 없기 때문에 403 오류가 발생한다
- 볼륨이 위치한 worker1에 tar 파일 풀기
- pv 파드가 Retain 상태인걸 확인한다.
kubectl patch pvc task-pv-claim -p '{"metadata":{"finalizers":null}}'
kubectl patch pv task-pv-volume -p '{"metadata":{"finalizers":null}}'
- patch 명령어를 활용하여 pvc,pvc 지우기
- patch 명령어 먼저 수행 후 delete
# nfs
# yum install -y nfs-utils.x86_64
# mkdir /nfs_shared
# chmod 777 /nfs_shared/ # 누구나 접속 가능하도록
# echo '/nfs_shared 192.168.0.0/21(rw,sync,no_root_squash)' > /etc/exports # 강의실 IP 대역대로 설정
# systemctl enable --now nfs
# systemctl status firewlld
# systemctl stop firewalld # 방화벽 멈추기
# vi nfs-pv.yaml
- Docker 서버에서 nfs inatsall 진행 후 방화벽 열어주기
# vi nfs-pv.yaml
----
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # Pod나 PVC가 지워져도 PV 유지
nfs:
server: 192.168.1.148 # nfs를 설치한 서버(docker 서버)
path: /nfs_shared # host path가 아니라 nfs라는 공간에 IP를 따로 부여하여 PV로 사용
# kubectl apply -f nfs-pv.yaml
# kubectl get pv
- nfs-pv 생성 yaml파일
# vi nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany # 읽고 쓰는 권한을 주면서 접근하는 클라이언트가 다수일때 쓰는 접근 모드
resources:
requests:
storage: 10Mi
# kubectl apply -f nfs-pvc.yaml
# kubectl get pvc
# kubectl get pv
- nfs-pvc yaml 파일 생성
## pod대신 deployment에서 진행
# vi nfs-pvc-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-pvc-deploy
spec:
replicas: 4 # 4개의 pod를 생성
selector:
matchLabels:
app: nfs-pvc-deploy
template:
metadata:
labels:
app: nfs-pvc-deploy
spec:
containers:
- name: nginx
image: 192.168.1.148:5000/nginx:latest
volumeMounts:
- name: nfs-vol # volume 이름
mountPath: /usr/share/nginx/html # 볼륨이 위치할 container안 경로
volumes:
- name: nfs-vol
persistentVolumeClaim:
claimName: nfs-pvc
- deploy용 yaml 파일 생성
# kubectl delete svc --all
# kubectl apply -f nfs-pvc-deploy.yaml
# kubectl get pod
# kubectl exec -it nfs-pvc-deploy-76bf944dd5-6j9gf -- /bin/bash
# kubectl expose deployment nfs-pvc-deploy --type=LoadBalancer --name=nfs-pvc-deploy-svc1 --port=80
- 마운트 경로가 위치할 worker1과 worker2가 nfs 시스템을 마운트하는 방법을 모르기 때문에 발생하는 에러
- worker1과 worker2에 nfs-utils 설치
- yum install -y nfs-utils.x86_64
- worker1, worker2 df -h
# ConfigMap
- 평범한 config 설정
- password나 외부에 노출이 꺼려지는 정보를 담지 않는다.
* 컨피그맵은 키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트입니다. 파드는 볼륨에서 환경 변수, 커맨드-라인 인수 또는 구성 파일로 컨피그맵을 사용할 수 있다. 컨피그맵을 사용하면 컨테이너 이미지에서 환경별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있다.
# vi configmap-dev.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-dev
namespace: default
data:
DB_URL: localhost
DB_USER: myuser
DB_PASS: mypass
DEBUG_INFO: debug
# kubectl apply -f configmap-dev.yaml
# kubectl describe configmaps config-dev
- configMap 만들기
# vi deployment-config01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configapp
labels:
app: configapp
spec:
replicas: 1
selector:
matchLabels:
app: configapp
template:
metadata:
labels:
app: configapp
spec:
containers:
- name: testapp
image: nginx
ports:
- containerPort: 8080
env: # 환경 변수 선언
- name: DEBUG_LEVEL
valueFrom:
configMapKeyRef:
name: config-dev
key: DEBUG_INFO
---
apiVersion: v1
kind: Service
metadata:
labels:
app: configapp
name: configapp-svc
namespace: default
spec:
type: NodePort
ports:
- nodePort: 30800
port: 8080
protocol: TCP
targetPort: 80 # containerport를 반드시 설정
selector:
app: configapp
# kubectl apply -f deployment-config01.yaml # deploy가 진행
# kubectl exec -it configapp-64d4554b68-v55g5 -- bash # pod 내부로 들어가기
- Deployment & configapp 서비스 생성
- 환경 변수를 이용한 검색
# vi configmap-wordpress.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config-wordpress
namespace: default
data:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: mode1752
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
# kubectl apply -f configmap-wordpress.yaml
# kubectl describe configmaps config-wordpress
- ConfigMap으로 워드프레스 만들기
# vi mysql-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
labels:
app: mysql-pod
spec:
containers:
- name: mysql-container
image: mysql:5.7
envFrom:
- configMapRef:
name: config-wordpress
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
type: ClusterIP
selector:
app: mysql-pod
ports:
- protocol: TCP
port: 3306
targetPort: 3306
kubectl apply -f mysql-pod-svc.yaml
- mysql pod 만들기
# vi wordpress-pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
labels:
app: wordpress-pod
spec:
containers:
- name: wordpress-container
image: wordpress
env: # 환경 변수
- name: WORDPRESS_DB_HOST
value: mysql-svc:3306 # DB의 서비스명을 DNS처럼 사용(위에서 만들었던 mysql 서비스)
- name: WORDPRESS_DB_USER
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_USER
- name: WORDPRESS_DB_PASSWORD
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_PASSWORD
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_DATABASE
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
type: LoadBalancer
# externalIPs:
# - 192.168.56.103
selector:
app: wordpress-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
# kubectl apply -f wordpress-pod-svc.yaml
- wordpress-pod 생성
# vi mysql-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
labels:
app: mysql-deploy
spec:
replicas: 1
selector:
matchLabels:
app: mysql-deploy
template:
metadata:
labels:
app: mysql-deploy
spec:
containers:
- name: mysql-container
image: mysql:5.7
envFrom:
- configMapRef:
name: config-wordpress
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
type: ClusterIP
selector:
app: mysql-deploy
ports:
- protocol: TCP
port: 3306
targetPort: 3306
# vi wordpress-deploy-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
labels:
app: wordpress-deploy
spec:
replicas: 1
selector:
matchLabels:
app: wordpress-deploy
template:
metadata:
labels:
app: wordpress-deploy
spec:
containers:
- name: wordpress-container
image: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql-svc:3306
- name: WORDPRESS_DB_USER
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_USER
- name: WORDPRESS_DB_PASSWORD
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_PASSWORD
- name: WORDPRESS_DB_NAME
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_DATABASE
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
type: LoadBalancer
# externalIPs:
# - 192.168.1.102
selector:
app: wordpress-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
- pod를 배포하는 것이 아니라 deployment로 작업; 확장성이 더 좋아진다.
# namespace 관리
kubectl get namespaces
kubectl config get-contexts kubernetes-admin@kubernetes
kubectl config set-context kubernetes-admin@kubernetes --namespace=kube-system
kubectl config get-contexts kubernetes-admin@kubernetes
kubectl config set-context kubernetes-admin@kubernetes --namespace=default
kubectl create namespace test-namespace
kubectl get namespace
kubectl config set-context kubernetes-admin@kubernetes --namespace=test-namespace
kubectl config set-context kubernetes-admin@kubernetes --namespace=default
# ResourceQuota
- namespace안에서 리소스 사용량 제한
# vi sample-resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: sample-resourcequota
namespace: default
spec:
hard:
count/pods: 5
# kubectl describe resourcequotas sample-resourcequota
# kubectl api-resources | grep resourcequotas
# kubectl run pod new-nginx --image=nginx
- 최대 다섯개만 생성이 가능하다
- kubectl run new-nginx[n] -n test-namespace --image=192.168.1.148:5000/nginx:latest
- 위의 명령어를 활용하여 pod를 하나씩 생성해 본다.
## 다양한 제한사항
apiVersion: v1
kind: ResourceQuota
metadata:
name: sample-resourcequota-usable
namespace: hyeongyun
spec:
hard:
requests.cpu: 1 # 1000m / 4(pod의 수) = 250ml (milli core); 코어를 쪼갤 수 있다
requests.memory: 1Gi # 1Gi / 4 = 250Mi
requests.ephemeral-storage: 5Gi# 스토리지 용량 제한
requests.nvidia.com/gpu: 2
limits.cpu: 4
limits.memory: 2Gi
limits.ephemeral-storage: 10Gi
limits.nvidia.com/gpu: 4
## pod생성
# vi sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
namespace: hyeongyun
spec:
containers:
- name: nginx-container
image: 192.168.1.148:5000/nginx:latest
- CPU와 메모리 정도는 명확하게 제한사항을 설정해야한다
** sample-resource.yaml 파일 추가
# vi sample-resource.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-resource
namespace: hyeongyun
spec:
replicas: 4 # 하나의 CPU를 4등분해서 사용한다.
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: 192.168.1.148:5000/nginx:latest
resources:
requests: # 최소
memory: "250Mi"
cpu: "250m"
limits: # 최대
memory: "500Mi"
cpu: "1000m"
# kubectl apply -f sample-resource.yaml
- kubectl -n hyeongyun describe resourcequotas sample-resourcequota-usable # sample-resourcequota-usable 세부 확인
- kubectl delete -f sample-resource.yaml : 파일 삭제
## LimitRange
** 위의 sample에서 정의한 CPU와 Memory를 바탕으로 제한 사항 설정
# vi sample-limitrange-container.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: sample-limitrange-container
namespace: hyeongyun
spec:
limits:
- type: Container
default: # limit
memory: 500Mi
cpu: 1000m
defaultRequest: # request
memory: 250Mi
cpu: 250m
max:
memory: 500Mi
cpu: 1000m
min:
memory: 250Mi
cpu: 250m
maxLimitRequestRatio: # 최소/최대 요청 비율
memory: 2
cpu: 4
- kubectl -n hyeongyun describe limitranges sample-limitrange-container : Limitrange 확인
** pod 생성
# vi sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: nginx-container
image: 192.168.1.148:5000/nginx:latest
- kubectl -n hyeongyun get pod
'Cloud Solution Architect > 쿠버네티스' 카테고리의 다른 글
Kubernetes6 (0) | 2023.06.09 |
---|---|
Kubernetes5 (0) | 2023.06.07 |
Kubernetes3 (0) | 2023.06.01 |
Kubernetes2 (0) | 2023.05.31 |
Kubernetes1 (0) | 2023.05.30 |