디렉토리를 k8slab > rapalab 을 만들고 시작
모든 노드를 실행하고 master에서 토큰을 발행하여 각 노드에서 해당 토큰을 이용한 뒤, 클러스터에 조인한다.
manager는 calico를 이용하여 네트워크 애드온을 설치한다. 이는 포드간 통신에 오버레이 네트워크를 제공할 수 있다. 또한, BGP를 이용하는 대규모 라우팅이 제공되는 환경이라면 이 역시 이용 가능한 플러그인으로 동작한다. 단, 우리 실습에서는 l2로 이용한다.
다음의 조건을 만족하는 웹서비스를 제공해 주세요
3개의 웹서비스 제공(nginx 이용)
Pod는 각각 0.5개의 CPU, 32MB 메모리가 기본적으로 제공된다.
만약, 각 Pod의 CPU 사용량이 80%를 넘어서게 되면 최대 10개까지 확장가능해야 한다.
nginx의 페이지는 ingress를 통해 라우팅 되어야 한다. 이는 nginx ingress controller을 이용하여 다음과 같이 구성한다.
vm port pod
211.183.3.20X → LB → Ingress Controller → Ingress → / → default 서비스 30001 3개
→ /shop → shop 서비스 30002 3개
→ /news → news 서비스 30003 3개
nfs를 구성하여 각 pod에 공간을 제공할 수 있어야 한다.
ingress controller는 LB와 연계하여 211.183.3.20X를 이용하고 있다. 이 IP 주소가 DNS를 통해 접속 할 수 있도록 했으면 좋겠지만
www.gildong.com을 manager의 /etc/hosts에 등록하고, manager에서는 curl을 이용해 확인해본다. (curl http://www.gildong.com/shop) 그 외에 곳에서는 브라우저+IP로 확인 (211.183.3.20X/shop 이렇게)
이 모든 작업은 rapa 고객이 요청하는 것이다. (namespace=rapa)
모든 노드를 실행하고 master에서 토큰을 발행하여 각 노드에서 해당 토큰을 이용한 뒤, 클러스터에 조인한다.
루트로 전환 su 후 실행
kubeadm init
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
kubeadm join 211.183.3.100:6443 --token 121m84.60y2tf2sjlsbyk1v \
--discovery-token-ca-cert-hash sha256:2c853acfd51fe383a325483cdd4e7d462ddceb05310863c2e23cfe1a535d7e98
root@manager:~# kubectl get node
NAME STATUS ROLES AGE VERSION
manager NotReady control-plane,master 65s v1.21.0
worker1 NotReady <none> 13s v1.21.0
worker2 NotReady <none> 12s v1.21.0
worker3 NotReady <none> 11s v1.21.0
docker login
manager는 calico를 이용하여 네트워크 애드온을 설치한다. 이는 포드간 통신에 오버레이 네트워크를 제공할 수 있다. 또한, BGP를 이용하는 대규모 라우팅이 제공되는 환경이라면 이 역시 이용 가능한 플러그인으로 동작한다. 단, 우리 실습에서는 l2로 이용한다.
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
root@manager:~# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-867d8d6bd8-cjn62 1/1 Running 0 3m13s
calico-node-6wn2d 1/1 Running 0 3m13s
calico-node-8hfpd 1/1 Running 0 3m13s
calico-node-q7x4j 1/1 Running 0 3m13s
calico-node-sf9fm 1/1 Running 0 3m13s
coredns-558bd4d5db-vrdt7 1/1 Running 0 5m48s
coredns-558bd4d5db-xtzvk 1/1 Running 0 5m48s
etcd-manager 1/1 Running 0 5m56s
...
다음의 조건을 만족하는 웹서비스를 제공해 주세요
- 외부로의 접속은 LB를 이용한다.(MetalLB)
- LB에서 제공하는 주소 대역은 211.183.3.231-211.183.3.249까지이다.
- Deployment
3개의 웹서비스 제공(nginx 이용)
Pod는 각각 0.5개의 CPU, 32MB 메모리가 기본적으로 제공된다.
만약, 각 Pod의 CPU 사용량이 80%를 넘어서게 되면 최대 10개까지 확장가능해야 한다.
nginx의 페이지는 ingress를 통해 라우팅 되어야 한다. 이는 nginx ingress controller을 이용하여 다음과 같이 구성한다.
vm port pod
211.183.3.20X → LB → Ingress Controller → Ingress → / → default 서비스 30001 3개
→ /shop → shop 서비스 30002 3개 → /news → news 서비스 30003 3개
kubectl create ns metallb-system
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
root@manager:~# mkdir k8slab
root@manager:~# cd k8slab/
root@manager:~/k8slab# mkdir rapalab
root@manager:~/k8slab# cd rapalab/
root@manager:~/k8slab/rapalab# ls
root@manager:~/k8slab/rapalab# touch metallb.yaml
root@manager:~/k8slab/rapalab# vi metallb.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 211.183.3.231-211.183.3.249
kubectl apply -f metallb.yaml
root@manager:~/k8slab/rapalab# kubectl create ns rapa
namespace/rapa created
root@manager:~/k8slab/rapalab# kubectl get ns | grep rapa
rapa Active 25s
root@manager:~/k8slab/rapalab# mkdir default
root@manager:~/k8slab/rapalab# mkdir shop
root@manager:~/k8slab/rapalab# mkdir news
apiVersion: apps/v1
kind: Deployment
metadata:
name: default
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: default
template:
metadata:
name: default # pod 이름
labels:
app: default
spec:
containers:
- name: default
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
name: default
namespace: rapa
spec:
ports:
- name: default-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30001
selector:
app: default
type: NodePort
배포하기
root@manager:~/k8slab/rapalab/default# kubectl apply -f default-deploy-svc.yaml
deployment.apps/default created
service/default created
apiVersion: apps/v1
kind: Deployment
metadata:
name: shop
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: shop
template:
metadata:
name: shop # pod 이름
labels:
app: shop
spec:
containers:
- name: shop
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
name: shop
namespace: rapa
spec:
ports:
- name: shop-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30002
selector:
app: shop
type: NodePort
배포하기
root@manager:~/k8slab/rapalab/shop# kubectl apply -f shop-deploy-svc.yaml
deployment.apps/shop created
service/shop created
apiVersion: apps/v1
kind: Deployment
metadata:
name: news
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: news
template:
metadata:
name: news # pod 이름
labels:
app: news
spec:
containers:
- name: news
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
name: news
namespace: rapa
spec:
ports:
- name: news-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30003
selector:
app: news
type: NodePort
배포하기
root@manager:~/k8slab/rapalab/news# kubectl apply -f news-deploy-svc.yaml
deployment.apps/news created
service/news created
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
ingress-config.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
namespace: rapa
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: default
port:
number: 80 # 서비스(nodeport)의 포트
- path: /shop
pathType: Prefix
backend:
service:
name: shop
port:
number: 80
- path: /news
pathType: Prefix
backend:
service:
name: news
port:
number: 80
배포하기
root@manager:~/k8slab/rapalab# kubectl apply -f ingress-config.yaml
ingress.networking.k8s.io/ingress-nginx created
확인하기
root@manager:~/k8slab/rapalab# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-nginx <none> * 211.183.3.231 80 3m40s
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
vi components.yaml
136번째 줄 추가
root@manager:~/k8slab# kubectl apply -f components.yaml
default (default 디렉토리에서)
root@manager:~/k8slab/rapalab/default# kubectl autoscale deploy default -n rapa --cpu-percent=10 --min=3 --max=10
horizontalpodautoscaler.autoscaling/default autoscaled
shop (shop 디렉토리에서)
root@manager:~/k8slab/rapalab/shop# kubectl autoscale deploy shop -n rapa --cpu-percent=10 --min=3 --max=10
horizontalpodautoscaler.autoscaling/shop autoscaled
news(news 디렉토리에서)
root@manager:~/k8slab/rapalab/news# kubectl autoscale deploy news -n rapa --cpu-percent=8010 --min=3 --max=10
horizontalpodautoscaler.autoscaling/news autoscaled
지우고 다시하려면
kubectl get hpa -n rapa 해서 kubectl delete -n rapa 이름
root@manager:~/k8slab/rapalab/news# kubectl top no --use-protocol-buffers ; kubectl get hpa -n rapa
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
manager 431m 10% 2326Mi 61%
worker1 192m 4% 1037Mi 56%
worker2 190m 4% 946Mi 51%
worker3 192m 4% 990Mi 53%
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
default Deployment/default 0%/80% 3 10 3 2m
news Deployment/news 0%/80% 3 10 3 23s
shop Deployment/shop 0%/80% 3 10 3 68s
ab -c 1000 -n 200 -t 60 http://211.183.3.231/
ab -c 1000 -n 200 -t 60 http://211.183.3.231/shop/
ab -c 1000 -n 200 -t 60 http://211.183.3.231/news/
root@manager:~/k8slab/rapalab/news# kubectl top no --use-protocol-buffers ; kubectl get hpa -n rapa
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
manager 537m 13% 2276Mi 60%
worker1 311m 7% 973Mi 52%
worker2 483m 12% 946Mi 51%
worker3 391m 9% 983Mi 53%
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
default Deployment/default 0%/10% 3 10 10 108s
news Deployment/news 0%/8010% 3 10 3 80s
shop Deployment/shop 0%/10% 3 10 3 94s
nfs를 구성하여 각 pod에 공간을 제공할 수 있어야 한다.
- 3의 연장선으로, default 서비스는 nfs 서버의 /default/index.html로 연결이 되도록
- shop 서비스는 nfs 서버의 /shop/index.html 으로 연결이 되도록
- news 서비스는 nfs 서버의 /news/index.html 로 연결이 되도록
- 페이지의 내용은 자유롭게
master
apt install -y nfs-server # manager에는 nfs 서버 설치
systemctl enable nfs-server --now
mkdir default
chmod 777 default/
mkdir shop
chmod 777 shop/
mkdir news
chmod 777 news/
<h3>Default Page @.@</h3>
<h3>Shop Page #_#</h3>
<h3>News Page -_-</h3>
vi /etc/exports
/root/default 211.183.3.0/24(rw,no_root_squash,sync)
/root/shop 211.183.3.0/24(rw,no_root_squash,sync)
/root/news 211.183.3.0/24(rw,no_root_squash,sync)
ufw disable
systemctl restart nfs-server
apt install -y nfs-common # worker에는 nfs client 설치
worker에서 확인
showmount -e 211.183.3.100
apiVersion: apps/v1
kind: Deployment
metadata:
name: default
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: default
template:
metadata:
name: default # pod 이름
labels:
app: default
spec:
containers:
- name: default
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
volumeMounts:
- name: default-volume
mountPath: /usr/share/nginx/html
volumes:
- name: default-volume
nfs:
path: /root/default
server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
name: default
namespace: rapa
spec:
ports:
- name: default-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30001
selector:
app: default
type: NodePort
root@manager:~/k8slab/rapalab/default# kubectl apply -f default-deploy-svc.yaml
deployment.apps/default created
service/default created
apiVersion: apps/v1
kind: Deployment
metadata:
name: shop
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: shop
template:
metadata:
name: shop # pod 이름
labels:
app: shop
spec:
containers:
- name: shop
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
volumeMounts:
- name: shop-volume
mountPath: /usr/share/nginx/html
volumes:
- name: shop-volume
nfs:
path: /root/shop
server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
name: shop
namespace: rapa
spec:
ports:
- name: shop-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30002
selector:
app: shop
type: NodePort
root@manager:~/k8slab/rapalab/shop# kubectl apply -f shop-deploy-svc.yaml
deployment.apps/shop created
service/shop created
apiVersion: apps/v1
kind: Deployment
metadata:
name: news
namespace: rapa
spec:
replicas: 3
selector:
matchLabels:
app: news
template:
metadata:
name: news # pod 이름
labels:
app: news
spec:
containers:
- name: news
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 500m
memory: 32Mi
volumeMounts:
- name: news-volume
mountPath: /usr/share/nginx/html
volumes:
- name: news-volume
nfs:
path: /root/news
server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
name: news
namespace: rapa
spec:
ports:
- name: news-port
port: 80 # 'service'의 port
targetPort: 80 # Pod's port
nodePort: 30003
selector:
app: news
type: NodePort
root@manager:~/k8slab/rapalab/news# kubectl apply -f news-deploy-svc.yaml
deployment.apps/news created
service/news created
ingress controller는 LB와 연계하여 211.183.3.20X를 이용하고 있다. 이 IP 주소가 DNS를 통해 접속 할 수 있도록 했으면 좋겠지만
www.gildong.com을 manager의 /etc/hosts에 등록하고, manager에서는 curl을 이용해 확인해본다. (curl http://www.gildong.com/shop) 그 외에 곳에서는 브라우저+IP로 확인 (211.183.3.20X/shop 이렇게)
manager
vi /etc/hosts
211.183.3.231 www.gildong.com