1. metallb
metallb는 DHCP
metallb가 IP를 loadbalancer에게 또 준다
# vi /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml # 이미지 수정하기 bitnami에서 사설 레포지토리로 수정
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml # metallb
# vi metallb-l2config.yaml # metallb의 DHCP 역할
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: nginx-ip-range
protocol: layer2
addresses:
- 192.168.2.112/32
- 192.168.2.113/32
- 192.168.2.114/32
# kubectl apply -f metallb-l2config.yaml
# kubectl get pods -n metallb-system -o wide # controller와 speaker가 생성된다
# kubectl describe configmaps -n metallb-system
# vi metallb-test.yaml # metallb pod, svc 생성
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod-container
image: nginx
---
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와 service 1개씩 만들어진다
# vi metallb-test1.yaml
# kubectl apply -f metallb-test1.yaml
# kubectl get svc
접속테스트
2. Volume
Volume
- pv/pvc
# pv-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Mi
accessModes:
- ReadWriteOnce
hostPath: # PV 마운트 위치
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Mi
selector:
matchLabels:
type: local # PV와 PVC 연결. 10Mi-1Mi 연결
---
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: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts: # 컨테이너 마운트 위치
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
# kubectl apply -f pv-pvc-pod.yaml
# kubectl get pod -o wide # worker1에 파드가 생성되었다
# kubectl get svc -o wide # metallb 생성할 때 만들었던 service의 SELECTOR Labels를 pv-pvc-pod로 변경할 것
# kubectl edit svc loadbalancer-service-pod
# kubectl get svc -o wide # worker1에 pod가 생겼다
# kubectl get svc
접속테스트 # Forbidden이 나오는 이유는 마운트가 잘 되었다는 이야기.컨테이너 /usr/share/nginx/html 경로에 index.html이 있지만 host path의 내용이 들어가기 때문이다. 마운트되면 원래 있었던 파일들은 경로가 바뀌어서 안보이게 된다
난 이게 떠서 svc2로 바꿈(잘못된 것이 아닌 114로 접근해야 한다)
worker1에 마운트가 되었다
worker1 노드에 gcp.tar파일을 업로드
# tar xvf gcp.tar -C /mnt/data/ # 여기에 웹페이지 파일을 넣어두면 홈페이지경로가 된다
접속테스트 # 왜 114에 뜨는거야 @@@@@. metallb가 부여해준 svc external-ip는 노드 서버의 IP와 다르다
* rm -rf /mnt/data
* kubectl apply -f .
* echo "HELLO" > /mnt/data/index.html
* kubectl delete pod task-pv-pod
* kubectl delete pvc task-pv-claim
* Retain 동일한 스토리지 자산을 재사용하려는 경우, 동일한 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다.
※ pv, pvc 지우는 방법
# kubectl delete pod task-pv-pod # pv 지우는 방법
# kubectl get pv,pvc # pvc_name 이름 확인하기
# kubectl patch pvc pvc_name -p '{"metadata":{"finalizers":null}}' # pvc patch를 먼저 해줘야 지울 수 있다
# kubectl delete pvc task-pv-claim
# kubectl delete pv task-pv-volume
// kubectl patch pv pv_name -p '{"metadata":{"finalizers":null}}'
// kubectl patch pod pod_name -p '{"metadata":{"finalizers":null}}'
task-pv-pod 재생성
pod가 worker1에 생성되었다
여전히 worker1에 데이터가 남아있다
지웠다가 다시 접속했지만 데이터가 남아있다
# kubectl get svc -n ingress-nginx
3. NFS
컨테이너 단위에서 지워지면 PV 데이터는 지워지지 않는다
워커 노드가 지워지면 디스크 공간에 있던 소스코드를 날릴 수 있기 때문에 NFS를 이용한다
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
# systemctl enable --now nfs
# sestatus # disabled 되었는지 확인
# systemctl status firewalld # 현재 방화벽이 활성화되어있다
# systemctl stop firewalld # nfs 포트번호를 열어주는 것이 좋지만 시간상 멈춤. mountd 뭐시기
master1 서버에서 진행
# mkdir volume-nfs && cd $_
# vi nfs-pv.yaml # PV 스크립트
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany # 여러 곳에서 접근할 수 있도록 허용
persistentVolumeReclaimPolicy: Retain # PV가 지워져도 데이터를 유지함
nfs:
server: 192.168.1.157 # nfs를 설치한 도커 서버IP
path: /nfs_shared
# kubectl apply -f nfs-pv.yaml # PV 생성
# kubectl get pv
# vi nfs-pvc.yaml # PVC 스크립트
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Mi
# kubectl apply -f nfs-pvc.yaml # PVC 생성
# kubectl get pvc
# kubectl get pv # RWX는 RW가 Many라는 뜻. # PV의 STATUS가 Bound로 변경되면서 CLAIM에 PVC와 연결되었다
# vi nfs-pvc-deploy.yaml # Deployment를 PVC 연결
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-pvc-deploy
spec:
replicas: 4
selector:
matchLabels:
app: nfs-pvc-deploy
template:
metadata:
labels:
app: nfs-pvc-deploy
spec:
containers:
- name: nginx
image: 192.168.1.157:5000/nginx:latest
volumeMounts: # NFS와 마운트할 지점
- name: nfs-vol
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-vol # 연결할 PV에서
persistentVolumeClaim:
claimName: nfs-pvc # 연결할 PVC
# kubectl apply -f nfs-pvc-deploy.yaml # Deployment 생성
# kubectl get pod # ContainerCreating이 계속 된다..
# kubelctl describe pod nfs-pvc-deploy-6fb7456ccf-42pm6 # worker1에 2개 worker2에 2개 총 4개의 pod(container)를 배포하는 과정에서 worker1과 worker2에 nfs-utils를 설치하지 않았기 때문에 nfs타입을 몰라서 fs type 에러가 난다
worker1과 worker2에 nfs-utils를 설치해줘야한다
# yum install -y nfs-utils.x86_64 # nfs-server뿐 아니라 nfs-client로 이용하기 위해서 설치가 필요하다
다시 master1으로 돌아와서
# kubectl get pod -o wide # 정상적으로 Running이 되었다
# kubectl get svc
# kubectl delete svc --all # metallb에 등록된 svc IP를 확보하기 위해 기존 svc 삭제
// # 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 # metallb가 external-ip를 자동으로 부여해줄 것이다
# kubectl get svc
접속테스트 # Forbidden이 나옴. nfs 마운트 경로에 아무것도 없기 때문
worker1 worker2 서버에서
# df -h # 쿠버네티스는 리눅스 마운트를 활용하고 있다
4. NFS 마운트 지점에 홈페이지 꾸미기
홈페이지 꾸미기
# tar xvf food.tar -C /nfs_shared/ # nfs 마운트 지점에 tar파일 풀기
접속테스트 # 클러스터가 박살이 나도 NFS서버는 밖에 존재하기 때문에 홈페이지 정상적으로 뜬다
5. configMap, 워드프레스 db서버 configmap
configMap 관리
- 컨피그맵은 컨테이너를 필요한 환경 설정을 컨테이너와 분리해서 제공하는 기능이다.
- 개발용과 상용 서비스에서는 서로 다른 설정이 필요할 때가 많다.
- 사용하는 데이터베이스가 다를 수도 있고, 실제 개발할 때는 디버그 모드로 로그를 출력하는데, 서비스용에서는 시스템 정보를 나타내는 모드로 로그를 출력해야 하는 등의 차이가 있다.
- 이렇게 다른 설정으로 컨테이너를 실행해야 할 때 사용하는 것이 컨피그맵이다.
- 컨피그맵을 컨테이너와 분리하면 컨테이너 하나를 개발용, 상용 서비스를 운영하기 전 보안이나 성능 장애 등을 검증하는 스테이지용, 상용 서비스용으로 사용할 수 있다.
configMap
- 컨피그맵은 키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트다.
- 파드는 볼륨에서 환경 변수, 커맨드-라인 인수 또는 구성 파일로 컨피그맵을 사용할 수 있다.
- 컨피그맵을 사용하면 컨테이너 이미지에서 환경별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있다.
# mkdir configmap && cd $_
# 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
# 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 # 환경변수로 configmap의 키값을 가지고 옴
valueFrom:
configMapKeyRef:
name: config-dev
key: DEBUG_INFO # configmap에 있는 키의 값을 가져옴
---
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 # 파드 포트 번호. 안적어주면 서비스의 포트번호 8080 으로 지정된다
selector:
app: configapp
# kubectl apply -f deployment-config01.yaml
# kubectl get svc
# curl 10.96.71.135:8080 # 접속테스트
# kubectl get pod
# kubectl exec -it configapp-64d4554b68-v55g5 -- bash # configapp 환경 변수를 세팅한 pod 접속
# env # pod에 정의된 환경변수 출력
# echo $DEBUG_LEVEL # 환경 변수 검색
# exit
워드프레스 configMap(dbserver)
# vi configmap-wordpress.yaml # 워드프레스 configmap 환경변수 스크립트
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
# vi mysql-pod-svc.yaml # db서버 pod, svc 스크립트
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
# kubectl get pod
6. 워드프레스 web서버 configmap
master1에서 mysql 접속해서 환경변수가 세팅되었는지 확인하기
# yum install -y mysql
# kubectl get svc
# mysql -h 10.107.25.186 -u wpuser -p # 환경 변수 적용으로 로그인이 된다
# vi wordpress-pod-svc.yaml # web서버 pod, svc 스크립트
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 # ClusterIP 10x.x.x:3306 이라고 적어도 된다
- name: WORDPRESS_DB_USER # wpuser 변수 가져옴
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_USER
- name: WORDPRESS_DB_PASSWORD # wppass 변수 가져옴
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_PASSWORD
- name: WORDPRESS_DB_NAME # db 이름 변수 가져옴
valueFrom:
configMapKeyRef:
name: config-wordpress
key: MYSQL_DATABASE
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
type: LoadBalancer
# externalIPs: # metallb가 자동으로 externalip를 제공해준다
# - 192.168.56.103
selector:
app: wordpress-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
# kubectl apply -f wordpress-pod-svc.yaml
# kubectl get pod,svc
접속테스트 # 환경변수로 db가 연결되었기 때문에 바로 언어 선택 화면으로 넘어간다
metallb에서 나의 IP 대역으로 설정하기
# vi metallb-l2config.yaml # metallb에 나의 IP 대역 등록하기
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: nginx-ip-range
protocol: layer2
addresses:
- 192.168.5.201-192.168.5.250
# - 192.168.2.112/32
# - 192.168.2.113/32
# - 192.168.2.114/32
# kubectl apply -f metallb-l2config.yaml # 수정내용 적용
# kubectl get svc # 아직 안바뀌었음
# kubectl delete svc wordpress-svc # config 워드프레스 svc 삭제
# kubectl apply -f wordpress-pod-svc.yaml # 다시 생성했지만 IP가 적용되지 않음
# kubectl delete -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml # speaker와 controller를 삭제
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
# kubectl apply -f metallb-l2config.yaml
# kubectl get pod -n metallb-system # metallb pod가 생성되었는지 확인
# kubectl get svc
접속테스트 - 안됨. 해당 IP에 대한 VM이 켜져있어야 한다
# kubectl delete -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml # 원복하기 위해 speaker, controller 삭제
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml # speaker, controller 생성
# 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.112/32
- 192.168.2.113/32
- 192.168.2.114/32
# kubectl apply -f metallb-l2config.yaml
# kubectl get svc
접속테스트
7. configmap db서버 deployment, namespace
# kubectl delete all --all # 이제 pod로 배포하지 않고 deployment로 배포할 것
# vi mysql-deploy-svc.yaml # configmap db서버 deployment 배포
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
name: default
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 # 타입을 적지 않아도 ClusterIP로 생성된다
selector:
app: mysql-deploy
ports:
- protocol: TCP
port: 3306
targetPort: 3306
# kubectl apply -f mysql-deploy-svc.yaml
# kubectl get pod,svc # db서버 deployment가 생성되었다. mysql로 접속하면 접속이 될 것이다
# vi wordpress-deploy-svc.yaml # wordpress 웹서버 deployment 스크립트
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: # metallb가 부여해준다
# - 192.168.1.102
selector:
app: wordpress-deploy
ports:
- protocol: TCP
port: 80
targetPort: 80
# kubectl apply -f wordpress-deploy-svc.yaml
# kubectl get all # dockerhub 한도 초과로 인해 ImagePullBackOff가 떴다
# kubectl describe pod/wordpress-deploy-57787cfd48-gz2pw
-- docker서버에 wordpress 이미지가 없다. master1에는 이미지 있음
master1에서 push하고
# docker push 192.168.1.157:5000/wordpress:latest
docker서버에서 docker 프라이빗 리포지토리에서 pull
# docker pull 192.168.1.157:5000/wordpress:latest
#
# 이미지 경로를 고치고
# kubectl apply -f wordpress-deploy-svc.yaml # 생성
# kubectl get svc
접속테스트
- namespace 관리
- 네임스페이스는 쿠버네티스 클러스터 하나를 여러 개 논리적인 단위로 나눠서 사용하는 것이다.
- 네임스페이스 덕분에 쿠버네티스 클러스터 하나를 여러 개 팀이나 사용자가 함께 공유할 수 있다.
- 또한 클러스터 안에서 용도에 따라 실행해야 하는 앱을 구분할 때도 네임스페이스를 사용한다
- 네임스페이스별로 별도의 쿼터를 설정해서 특정 네임스페이스의 사용량을 제한할 수도 있다.
# kubectl get ns
# kubectl config get-contexts
# kubectl config set-context kubernetes-admin@kubernetes --namespace kube-system # 네임스페이스 변경
# kubectl config get-contexts # kube-system으로 변경되었다
# kubectl create namespace test-namespace # namespace 만들기
# kubectl config set-context kubernetes-admin@kubernetes --namespace test-namespace
ResourceQuota : 사용량 제한
- 소스 쿼터를 사용하여 각 네임스페이스마다, 즉 가상 쿠버네티스 클러스터마다 사용 가능한 리소스를 제한할 수 있다.
- 리소스 쿼터는 생성이나 변경으로 그 시점에 제한이 걸린 상태가 되어도 이미 생성된 리소스에는 영향을 주지 않기 때문에 주의해야 한다.
- 리소스 쿼터는 크게 '생성 가능한 리소스 수 제한'과 '리소스 사용량 제한'으로 나눌 수 있다.
# mkdir resourcequota && cd $_
# vi sample-resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: sample-resourcequota
namespace: test-namespace
spec:
hard: # 엄격
count/pods: 5
# kubcectl apply -f sample-resourcequota.yaml
8. ResourceQuota
# kubectl api-resources | grep resourcequotas
# kubectl describe quota sample-resourcequota # 현재 5개 한도에서 1개가 생성되어있다
# kubectl run pod new-nginx1 -n test-namepace --image=192.168.1.157:5000/nginx:latest # pod를 만드는 명령. create는 deployment를 만드는 명령
5개 이상으로 생성 시도를 하면 에러가 난다
# kubectl describe quota sample-resourcequota
# kubectl create ns peach # 한도를 피하기 위해 새로운 namespace 생성
# vi sample-resourcequota-usable.yaml # 사용량 제한 규칙 생성
apiVersion: v1
kind: ResourceQuota
metadata:
name: sample-resourcequota-usable
namespace: peach # namespaece 바꾼다
spec:
hard:
requests.memory: 2Gi # request = 최소 용량
requests.storage: 5Gi
sample-storageclass.storageclass.storage.k8s.io/requests.storage: 5Gi
requests.ephemeral-storage: 5Gi
requests.nvidia.com/gpu: 2 # 4코어
limits.cpu: 4 # limits = 최대 늘어날 수 있는 수치
limits.ephemeral-storage: 10Gi
limits.nvidia.com/gpu: 4
# kubectl apply -f sample-resourcequota-usable.yaml
# vi sample-pod.yaml # CPU 개수, memory 용량을 정의하지않은 deployment 스크립트
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
namespace: peach
spec:
containers:
- name: nginx-container
image: 192.168.1.157:5000/nginx:latest
# kubectl apply -f sample-pod.yaml # 에러가 난다. CPU 개수, memory 용량을 반드시 정의해야한다
# vi sample-resource.yaml # CPU 개수, memory 용량을 정의한 deployment 스크립트
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-resource
namespace: peach
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: 192.168.1.157:5000/nginx:latest
resources: # CPU 개수, Memory 용량 정의
requests: # 최소 용량
memory: "64Mi"
cpu: "50m" # 1코어=1000m
limits: # 최대 늘어날 수 있는 수치
memory: "128Mi"
cpu: "100m"
# kubectl apply -f sample-resource.yaml
# kubectl -n peach get pod
# kubectl describe -n peach resourcequotas sample-resourcequota-usable # 사용량과 제한량을 확인할 수 있음
댓글