Kubernetes
VM 세팅




세 VM의 맥 주소를 확인해서 기존 아이피와 겹치지 않도록 해준다
## 생성한 세 개의 VM에 모두 적용
# MobaXterm에서 세팅
yum update -y
# 각자 호스트 네임 설정
hostnamectl set-hostname [각자의 이름]
# 호스트에 아이피 정보 입력
cat <<EOF >> /etc/hosts
192.168.2.95 master1
192.168.2.76 worker1
192.168.2.82 worker2
EOF
# 도커 설치
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/docker-ce.repo
yum --enablerepo=docker-ce-stable -y install docker-ce-19.03.15-3.el7
mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
# 설정 세팅
systemctl enable --now docker
systemctl daemon-reload
systemctl restart docker
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
## 스왑 기능 비활성화 (쿠버네티스 설치에 필수)
# Swap 기능은 본래 가용된 메모리보다 더 큰 메모리 할당을 가능하도록 하기 위함인데,
# 쿠버네티스는 주어진 인스턴스의 자원을 100% 최대한 사용하는 것이 목표이다.
# 그러므로 스왑 메모리를 켜놓으면 인스턴스 자원이 일관되지 않아 쿠버네티스의 목표에 부합되지 않기 때문.
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
# 쿠버네티스에 브리지 기능 활성화
cat <<EOF > /etc/sysctl.d/k8s.conf # kubernetes
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 커널에 적용
sysctl --system
reboot

Kubeadm 설치 (Multi Node: Master Node, Worker Node)
# 쿠버네티스 리포지토리 정보 입력
cat <<'EOF' > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
# kubeadm, kubelet, kubectl 설치
yum -y install kubeadm-1.19.16-0 kubelet-1.19.16-0 kubectl-1.19.16-0 --disableexcludes=kubernetes
systemctl enable kubelet
poweroff

Master Node
# 마스터 노드 init
kubeadm init --apiserver-advertise-address=192.168.2.95 --pod-network-cidr=10.244.0.0/16
# 자격증명
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 사이트로부터 kube-flannel.yml 파일을 가져와서 파드를 생성
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 자동 완성 설치(자동시작도 함께)
yum install -y bash-completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
# 재시작
exit
# 자동 완성 확인
kubectl get pods --all-namespaces

Worker Node
# 워커 노드에 위에서 발급받은 키 입력
kubeadm join 192.168.2.95:6443 --token b2shwr.lggzpgfjvgelgtk9 \
--discovery-token-ca-cert-hash sha256:26b0ceb68bab02ffb1ab60f1cc15c15c1e509fcbea3b9eb72f8bdc068aa81434
# 마스터 노드에서 노드 상태 확인
kubectl get nodes



Kubernetes - CLI
기본 사용법
# 폴더 생성 후 이동
mkdir workspace && cd $_
# kubectl [명령어] [유형] [자원 이름] [옵션]
# 네임스페이스 생성
kubectl create namespace kyounggu
# 노드 확인
kubectl get node
# 파드 생성 ('-n': namespace)
kubectl run nginx-pod -n kyounggu --image=kyounggu/web-site:aws
kubectl run nginx-pod2 -n kyounggu --image=kyounggu/web-site:aws



# 클러스터 아이피 추가
kubectl expose pod nginx-pod -n kyounggu --name clusterip --type ClusterIP --port 80
# 해당 네임스페이스의 서비스 확인
kubectl get svc -n kyounggu

# 노드 포트 추가
kubectl expose pod nginx-pod -n kyounggu --name nodeport --type NodePort --port 80




이처럼, 노드포트는 아무 노드의 아이피에 노드 포트를 통해 외부에서 접속이 가능하게 해준다.
# 로드 밸런서 추가
kubectl expose pod nginx-pod -n kyounggu --name loadbalancer --type LoadBalancer --external-ip [마스터1 아이피] --port 80


## 현재 context의 namespace 수정 방법 (매번 명령어마다 namespace를 입력하지 않아도 되게 해준다.)
# 현재 context 확인
kubectl config current-context
# context 정보 확인
kubectl config get-contexts kubernetes-admin@kubernetes
# namespace 정보 확인
kubectl get ns kyounggu
# context의 namespace 수정
kubectl config set-context kubernetes-admin@kubernetes --namespace kyounggu




# 워커1 접속
kubectl exec -it nginx-pod nginx-pod
# 워커2 접속
kubectl exec -it nginx-pod2 nginx-pod
# 테스트를 위해 워커1,2의 웹페이지 수정
//nginx
kubectl exec -it nginx-pod -- sh -c 'echo "<h1>web01</h1>" > /usr/share/nginx/html/index.html'
kubectl exec -it nginx-pod2 -- sh -c 'echo "<h1>web02</h1>" > /usr/share/nginx/html/index.html'
//apache
kubectl exec -it nginx-pod -- sh -c 'echo "<h1>web01</h1>" > /var/www/html/index.html'
kubectl exec -it nginx-pod2 -- sh -c 'echo "<h1>web02</h1>" > /var/www/html/index.html'
# 로드 밸런서 수정
kubectl edit svc loadbalancer
// selector의 라벨 부분 변경
run: nginx-pod2
//




템플릿으로 Service
nginx-pod
# nginx-pod 템플릿 생성
vi nginx-pod.yaml
//
apiVersion: v1
kind: Pod
metadata:
namespace: kyounggu
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod-container
image: nginx
ports:
- containerPort: 8080
//
# kubectl apply -f nginx-pod.yaml
## 중복된 이름이 있을 경우 삭제한다. kubectl delete all --all
# 포트 번호를 생략하면, nginx-pod의 템플릿의 컨테이너 포트를 따라간다 (8080)
kubectl expose pod nginx-pod --name clusterip --type ClusterIP
# 다시 삭제
kubectl delete svc clusterip

clusterip-pod
# clusterip-pod 템플릿 작성
vi clusterip-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
name: clusterip-pod
spec:
type: ClusterIP
# externalIPs:
# - 192.168.56.101
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80 # 변경이 되면 밑에 타겟포트를 80포트로 지정해야 한다.
# targetPort: 80
//
## port:80/targetport:x (o)
## port:8080/targetport:x (x)
## port:8080/targetport:80 (o)
# kubectl apply -f clusterip-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-pod
# kubectl edit svc clusterip-service-pod


nodeport-pod
# nodeport-pod 템플릿 작성
vi nodeport-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
name: nodeport-service-pod
spec:
type: NodePort
selector:
app: nginx-pod
ports:
- name: http-port
protocol: TCP
port: 6789
targetPort: 80 # 컨테이너 포트가 맞다.
nodePort: 30080
//
# kubectl apply -f nodeport-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-pod
# kubectl edit svc nodeport-service-pod

loadbalancer-pod
# loadbalancer-pod 템플릿 작성
vi loadbalancer-pod.yaml
//
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-pod
labels: # metadata에 서비스의 라벨을 붙여줄 수도 있다.
svc: nignx-pod-slb
spec:
type: LoadBalancer
externalIPs:
- [마스터1 아이피]
- [워커1 아이피]
- [워커2 아이피]
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 7890 # -p 7890:80
targetPort: 80
//
# kubectl apply -f loadbalancer-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-pod



ReplicaSet
replicaset
# replicaset 템플릿 작성
vi replicaset.yaml
//
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
labels:
app: replicaset
spec:
replicas: 3 # desired state (kube-controller-manager)
selector:
matchLabels:
app: nginx-replicaset
template:
metadata:
name: nginx-replicaset
labels:
app: nginx-replicaset
spec:
containers:
- name: nginx-replicaset-container
image: nginx
ports:
- containerPort: 80
name:
//
# kubectl apply -f replicaset.yaml
# kubectl get replicasets.apps -o wide
# kubectl describe replicasets.apps nginx-replicaset


clusterip-replicaset
# clusterip-replicaset 템플릿 생성
vi clusterip-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
name: clusterip-service-replicaset
spec:
type: ClusterIP
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 20080
targetPort: http-web-svc # 포트 번호가 아닌 라벨로도 가능
//
# kubectl apply -f clusterip-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-replicaset

nodeport-replicaset
# nodeport-replicaset 템플릿 생성
vi nodeport-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
name: nodeport-service-replicaset
spec:
type: NodePort
externalIPs: # 노드 포트는 안됨
- 192.168.2.95
- 192.168.2.76
- 192.168.2.82
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 10080
targetPort: http-web-svc
nodePort: 32080
//
# kubectl apply -f nodeport-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-replicaset

# clusterip-pod에 외부 아이피 추가
vi clusterip-pod.yaml
// 다음 항목을 spec에 추가
externalIPs:
- 192.168.2.95
- 192.168.2.76
- 192.168.2.82
//
# clusterip-service-replicaset에 외부 아이피 추가
kubectl edit svc clusterip-service-replicaset
// 다음 항목을 spec에 추가
externalIPs:
- 192.168.2.95
- 192.168.2.76
- 192.168.2.82
//



loadbalancer-replicaset
# loadbalancer-replicaset 템플릿 생성
vi loadbalancer-replicaset.yaml
//
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-replicaset
spec:
type: LoadBalancer
externalIPs:
- 192.168.2.95
- 192.168.2.76
- 192.168.2.82
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 8080
targetPort: http-web-svc
//
# kubectl apply -f loadbalancer-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-replicaset


Deployment
deployment
# deployment 템플릿 작성
vi deployment.yaml
//
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 4
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment-container
image: kyounggu/web-site:aws
ports:
- containerPort: 80
//
# kubectl apply -f deployment.yaml
# kubectl get deployments.apps -o wide
# kubectl describe deployments.apps nginx-deployment



clusterip-deployment
# clusterip-deployment 템플릿 생성
vi clusterip-deployment.yaml
//
apiVersion: v1
kind: Service
metadata:
name: clusterip-service-deployment
spec:
type: ClusterIP
externalIPs:
- 192.168.2.95 # 클러스터 아이피 하나만
selector:
app: nginx-deployment
ports:
- protocol: TCP
port: 81
targetPort: 80
//
# kubectl apply -f clusterip-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-deployment


nodeport-deployment
# nodeport-deployment 템플릿 생성
vi nodeport-deployment.yaml
//
apiVersion: v1
kind: Service
metadata:
name: nodeport-service-deployment
spec:
type: NodePort
selector:
app: nginx-deployment
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
//
# kubectl apply -f nodeport-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-deployment
새로 생성하지 않고 기존의 서비스를 재활용하여 사용할 수도 있다.
# 기존 노드 포트 서비스의 셀럭터 라벨 변경
kubectl edit svc nodeport-service-pod
// selector의 app을 변경
selector:
app: nginx-deployment
//



loadbalancer-replicaset
## 해당 과정은 생략했음
# vi loadbalancer-replicaset.yaml # 로드밸런서 야믈
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-replicaset
spec:
type: LoadBalancer
externalIPs:
- 192.168.1.188
- 192.168.1.211
- 192.168.1.216
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 80
targetPort: 80
# kubectl apply -f loadbalancer-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-replicaset
삭제 및 변경
원할한 테스트를 위해 deployment를 제외한 모든 것들을 제거
# 파드 삭제 ('--grace-period': 정상 종료 시간. 즉 0은 바로 종료, '--force': 강제)
kubectl delete pod --grace-period 0 --force nginx-pod
# 레플리카셋 삭제
kubectl delete rs nginx-replicaset

# 현재 4개의 scale을 5개로 증가
kubectl scale --current-replicas=4 --replicas=5 deployment/nginx-deployment
# 현재 값을 몰라도 무방하다.
kubectl scale --replicas=6 deployment/nginx-deployment
# scale in도 가능
kubectl scale --replicas=4 deployment/nginx-deployment



Deployment 롤링 업데이트 제어
# 이미지 변경
kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=halilinux/web-site:v1.0
# 다시 이미지 변경
kubectl set image deployment/nginx-deployment nginx-deployment-container=nginx
# 히스토리 확인
kubectl rollout history deployment nginx-deployment
# 히스토리의 리비전 정보 확인
kubectl rollout history deployment nginx-deployment --revision 2 # 리비전2 상세보기
# 롤백(전 단계로 복원)
kubectl rollout undo deployment nginx-deployment
# 롤백(원하는 리비전으로 복원)
kubectl rollout undo deployment nginx-deployment --to-revision 1 # 리비전2로 복원











멀티 컨테이너
VM설정
worker1, 2, docker의 메모리를 2048MB, 프로세서 개수를 1개로 줄인다.



초기화
## docker에 만일 남아있는 컨테이너, 이미지가 있으면 삭제
# 컨테이너 확인
docker ps -a
# 컨테이너 삭제
docker rm -f [컨테이너 이름]
# 이미지 확인
docker images
# 이미지 삭제
docker rmi -f [이미지 이름]


사설 레지스트리 이용
# docker에서 사설 레지스트리 컨테이너 생성 (자동 시작)
docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry
# worker1,2, master1에서 도커 데몬 설정 수정
vi /etc/docker/daemon.json
//
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"insecure-registries":["docker 아이피:5000"]
}
//
# 도커 재시작
systemctl restart docker
# 태그를 달고 이미지 전송
//nginx (worker1)에서
docker tag nginx:latest 192.168.1.158:5000/nginx:latest
docker push 192.168.1.158:5000/nginx:latest
//aws (worker2)에서
docker tag kyounggu/web-site:was 192.168.1.158:5000/web-site:aws
docker push 192.168.1.158:5000/web-site:aws
//food (worker3)에서
docker tag kyounggu/web-site:food 192.168.1.158:5000/web-site:food
docker push 192.168.1.158:5000/web-site:food
# 사설 레지스트리의 이미지를 확인하는 방법
curl -X GET http://192.168.1.158:5000/v2/_catalog
# 사설 레지스트리의 해당 이미지의 태그 확인
curl -X GET http://192.168.1.158:5000/v2/nginx/tags/list



miltipod
# master1, worker1, 2에서 도커 로그인
docker login
----------
# master1에서 폴더 이동
cd workspace
# master에서 multipod 템플릿 생성 (사설 레지스트리 사용)
vi multipod.yaml
//
apiVersion: v1
kind: Pod
metadata:
name: multipod
spec:
containers:
- name: nginx-container #1번째 컨테이너
image: 192.168.1.158:5000/nginx:latest
ports:
- containerPort: 80
- name: centos-container #2번째 컨테이너
image: 192.168.1.158:5000/centos:7
command:
- sleep
- "10000"
//
# 사설 레지스트리에 이미지 전송
docker tag centos:7 192.168.1.158:5000/centos:7
docker push 192.168.1.158:5000/centos:7
# kubectl apply -f multipod.yaml


# 멀티 파드에 접속 (첫번째 컨테이너로 접속됨)
kubectl exec -it multipod -- bash
# 현재 접속중인 컨테이너 정보 확인
cat /etc/os-release
# 나오기
exit
-----------
# 원하는 컨테이너로 접속 ( '-c': connect 명령어에 컨테이너 이름)
kubectl exec -it multipod -c centos-container -- bash
# 현재 접속중인 컨테이너 정보 확인
cat /etc/os-release





멀티 컨테이너 - wordpress
사설 저장소를 이용해 워드프레스 구축
# master1에서 mysql5.7 내려받기
docker pull mysql:5.7
# 저장소에 mysql5.7 업로드
docker tag mysql:5.7 192.168.1.158:5000/mysql:5.7
docker push 192.168.1.158:5000/mysql:5.7
# 최신 버전의 워드프레스 내려받기
docker pull wordpress
# 저장소에 워드프레스 업로드
docker tag wordpress:latest 192.168.1.158:5000/wordpress:latest
docker push 192.168.1.158:5000/wordpress:latest
# wp-multi-container 템플릿 생성
vi wp-multi-container.yaml
//
apiVersion: v1
kind: Pod
metadata:
name: wordpress-pod
labels:
app: wordpress-pod
spec:
containers:
- name: mysql-container
image: 192.168.1.158:5000/mysql:5.7
env:
- name: MYSQL_ROOT_HOST
value: '%' # wpuser@%
- name: MYSQL_ROOT_PASSWORD
value: mode1752
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wpuser
- name: MYSQL_PASSWORD
value: wppass
ports:
- containerPort: 3306
- name: wordpress-container
image: 192.168.1.158:5000/wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-pod:3306
- name: WORDPRESS_DB_USER
value: wpuser
- name: WORDPRESS_DB_PASSWORD
value: wppass
- name: WORDPRESS_DB_NAME
value: wordpress
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-deployment-wordpress
spec:
type: LoadBalancer
externalIPs:
- 192.168.2.95
selector:
app: wordpress-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
//
# 만일 파드 중에서 80포트를 사용하는 것이 있다면 externalIP 삭제
# kubectl edit svc clusterip-pod
# kubectl apply -f wp-multi-container.yaml





# HeidiSQL을 쓰기 위해 3306 포트도 추가
vi wp-multi-container.yaml
// 로드밸런스 서비스 부분의 포트를 다음과 같이 수정
ports:
- name: web-port
protocol: TCP
port: 80
targetPort: 80
- name: db-port
protocol: TCP
port: 3306
targetPort: 3306
//
# 변경사항 적용
kubectl apply -f wp-multi-container.yaml




# ClusterIP의 외부 아이피에 워커1을 추가하고 3306포트 개방, 셀렉터 변경
# 워커1을 통해 DB에 접속하기 위해
kubectl edit svc clusterip-pod
// 다음 항목을 수정
spec:
clusterIP: 10.104.122.251
externalIPs:
- 192.168.2.76
ports:
- name: web-port
port: 80
protocol: TCP
targetPort: 80
- name: db-port
port: 3306
protocol: TCP
targetPort: 3306
selector:
app: wordpress-pod
//



'메가존 클라우드 2기 교육 > 실무 특화' 카테고리의 다른 글
Kubernetes - NFS, configMap, namepsace, ResourceQuota (0) | 2023.06.05 |
---|---|
Kubernetes - Ingress, metallb, Volume (0) | 2023.06.05 |
Kubernetes - 미니큐브 CLI, 템플릿, 롤링 업데이트 제어 (0) | 2023.05.31 |
Docker - AWS ECS (0) | 2023.05.29 |
Docker - 도커 데이터 관리, onbuild 명령어 활용, 도커 사설 레지스트리, 도커 컴포즈, 도커 모니터링, 도커 스웜 (3) | 2023.05.26 |