Kubenetes
ReplicaSet
- 하나의 pod가 아니라 여러개의 pods를 관리하는 것이다.
- 원하는 용량(desired state)을 유지시키는 kube-contorll-manager의 역할을 한다.
실습 준비
mkdir replicaset && cd $_ : workspace를 만들어준다.
minikube start --driver=none : 미니큐브를 시작해준다.
vi replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
replicas: 3
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

kubectl apply -f replicaset.yaml
- kubectl apply 명령어로 replicaset을 실행시켜준다.
- 어제 작업했던 ClusterIP, NodePort, LoadBalancer가 pending상태로 대기중이다.
minikube에러
- minikube에서 메모리의 부족 혹은, minikube 자체의 에러때문에 pod의 삭제가 되지 않았다.
-> 멀티큐브로 넘어간다.
Multikube
전체 환경설정

- Centos7, CPU 2c, RAM 4Gb로 VM을 생성한다.
Docker 설치
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
- docker 웹사이트에서 docker-ce버전을 다운로드 한다.
sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/docker-ce.repo
- docker-ce.repo에서 enabled를 수정한다.
yum --enablerepo=docker-ce-stable -y install docker-ce-19.03.15-3.el7
- docker-ce-stable 버전을 설치해준다.
- 이때 버전이 19.03.15-3버전인데, 이 버전이 안정되어 있어 이 버전을 사용한다.
mkdir /etc/docker : 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
- tee명령어를 찾아보자.
systemctl enable --now docker
systemctl daemon-reload
- daemon-reload로 daemon(백그라운드실행)를 재부팅한다.
systemctl restart docker
- 도커 재실행

systemctl disable --now firewalld
- 방화벽을 꺼둔다.

setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
- selinux 종료한다.
- sed 명령어는 자주 쓰이니 알아보는것이 좋다.
쿠버네티스 설치
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
- kubernetes를 k8s라고 하기도 한다.
sysctl --system
reboot 확실하게 설정되도록 reboot한다.
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
- kubernetes의 repository를 정해준다.
yum -y install kubeadm-1.19.16-0 kubelet-1.19.16-0 kubectl-1.19.16-0 --disableexcludes=kubernetes
- kubeadm(kube abmin)으로 쿠버네티스를 설치한다.
- 최신버전은 20대가 넘어가지만 이슈가 존재하여 19버전을 사용한다.
- 또, 여기서의 좋은 기능도 존재한다.
systemctl enable kubelet
복제
- VM을 poweroff하고, 연결된 복제로, Worker1~2를 만들어준다.
- 또, 원본 VM을 Master1으로 한다.
- master1은 2~3 등 늘어날 수 있다는 뜻이다.

- 이렇게 Master1, Worker1~2 총 3개의 VM이 생성되었다.
- Worker의 스펙은 CPU 1c, RAM 1Gb 로해준다.
- 또, 네트워크로 가서 MAC주소를 바꿔준다.

- 그룹을 만들어서 최종적으로 이 모습이 되도록한다.
- minikube는 빠르게 실습할 때 사용하고, 왠만해서는 실습 환경이라고 이 환경에서 사용하는것이 좋다.
Master 환경설정

- init이 끝나면 다른 worker들이 join할 수 있도록 명령어가 출력된다. 이를 메모장에 적어둔다.
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
- 갑자기 kubectl apply가 나오는데, flannel이라는 도구를 이용하여, pod들간의 통신을 위한 모듈로 사용할 것이다.

kubeadm init --apiserver-advertise-address=[masterIPaddress] --pod-network-cidr=10.244.0.0/16
- 여기가 master노드인 것을 토큰으로 만들어 worker들에게 주는 것이다.
- 또, pod들간의 통신하는 IP범위를 정해주었다.
- 이 설치가 끝나면 스냅샷을 찍어준다.
kubectl get node를 보면 master, worker가 모두 출력된다.
kubectl completion bash

kubectl get pods --all-namespaces
- 모든 pod을 확인한다.
- flannel이 러닝중이다.
source <(kubectl completion bash)
- kubectl completion bash를 소스에 넣는다.
- echo "source <(kubectl completion bash)" >> ~/.bashrc
- 위 명령어를 ~/.bashrc 에 넣어, 재부팅해도 들어가도록 한다.
Multikube 실습
LoadBalancer
kubectl expose pod nginx-pod --name loadbalancer --type LoadBalancer --external-ip 192.168.1.214 --port 80
- 로드밸런서 타입으로 expose를 지정했다.

- IP주소로 잘 접속 된다.
pod와 service 정리하기

kubectl delete pod,svc --all
vi nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-pod
spec:
containers:
- name: nginx-pod-container
image: jo1132/web-site:v2.0
ports:
- containerPort: 8080
kubectl apply -f nginx-pod.yaml
vi clusterIP-pod.yaml
apiVersion: v1
kind: Service
metadata:
name: clusterip-service-pod
spec:
type: ClusterIP
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl apply -f clusterip-pod.yaml

- ClusterIP로 curl명령어로 확인해본다.

- HTML이 잘 출력된다.
vi nodeport-pod.yaml
apiVersion: v1
kind: Service
metadata:
name: nodeport-service-pod
spec:
type: NodePort
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort:30080

- clusterIP를 사용할 수 있다.
- 또, hostIP + 30080 주소로 웹브라우저에서 접근할 수 있다.

- 잘 접근 가능하다.
- 만약 pod 혹은 서비스에 수정이 필요하면 edit 명령어를 사용할 수 있다.
kubectl edit svc nodeport-service-pod
vi loadbalancer-pod.yaml
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-pod
spec:
type: LoadBalancer
externalIPs:
- 192.168.1.189
- 192.168.1.212
- 192.168.1.214
selector:
app: nginx-pod
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl apply -f loadbalancer-pod.yaml
- 로드밸런서를 실행해준다.

- 세 컨테이너 IP주소로 웹 브라우저 접근이 가능하다.
pod,service 정리

ReplicaSet
vi replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
replicas: 3
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

kubectl get replicasets.apps -o wide

kubectl get pod -o wide
- 도커swarm에서는 master도 task를 가지고 있었다.
- 그러나 kubernetes에서는 master는 pod를 배치, 스케쥴하지 않는다.
- 그래서 worker1, 2가 나뉘어 작업을 가져갔다.
kubectl edit replicaset

- edit 명령어로 서비스, pod을 수정한다.
- replicas를 찾아서 4로 수정해준다.
- 골고루 분배되어, worker1:2. worker2:2 두개씩 잘 분배되었다.
에러 1
- 한 강의실에서 너무 많은 이미지 PUlling이 있어서 PUll이 막였다.
- 로그인을 해줘도 안되서 도커 사설 레지스트리를 설정하여 이미지를 공유한다.
마스터
docker pull nginx
docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry
모두
vi /etc/docker/daemon.json
{ "insecure-registries":["저장소서버IP주소:5000"] }
- 위 코드를 맨 위에 넣는다.
systemctl restart docker
마스터
docker push 마스터IP주소:5000/nginx:latest
- 저장소서버(마스터)에 nginx:latest이미지를 업로드 한다.
kubectl apply -f replicaset.yaml 이제 레플리카셋을 올려준다.

- 모두 러닝중이다.
에러 2
- master와 worker 둘다 reboot하면 재부팅 후 docker가 안되는 문제가 생겼다.
- 도커 사설 레지스트리가 제대로 작동되지 않았다.
- 코드를 넣어줄때, 위에 넣어서 그런지 동작하지 않았다.
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
},
{ "insecure-registries":["192.168.1.189:5000"] }
insecure-registries코드를 제일 아래 넣어줘야 kubelet이 제대로 실행된다.
잠깐...

- insecure-registries코드를 아래로 내리니까, 도커 사설 레지스트리가 작동하지 않는다.
- 한 묶음(괄호)안에 넣어줘서 한번에 동작하게 넣어본다.
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"insecure-registries":["192.168.1.189:5000"]
}
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: 80
targetPort: 80

node는 4개인데 clusterIP는 하나?

- 현재 우리가 사용하는 clusterIP는 하나이다. 그러나 현재 실행되고 있는 node는 4개가 운영되고 있다. 이때, clusterIP는 어디랑 연결되어있는가?

- 똑같은 ClusterIP로 계속 curl명령어를 쳤을 떄, 숫자가 번갈아 나온다.
- 즉, 서비스 단위의 IP를 부여받는 것이라 할 수 있다.
vi loadbalancer-replicaset.yaml
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service-replicaset
spec:
type: LoadBalancer
externalIPs:
- [master1IP]
- [worker1IP]
- [worker2IP]
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 80
targetPort: 80

kubectl get svc
- 서비스가 잘 생성되었다.

- 접근도 잘 된다.
replicaset 정리
kubectl delete -f replicaset.yaml
- 파일명으로도 pod을 지울 수 있다.
- 그러나 service들은 지워지지 않는다.
kubectl delete pod,svc --all
Deployment
- replicaset과 거의똑같은데, 다만 kind정보만 다르다.
비교
replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: nginx-replicaset
template:
metadata:
name: nginx-replicaset
labels:
app: nginx-replicaset
spec:
containers:
- name: nginx-replicaset-container
image: 192.168.1.189:5000/nginx
ports:
- containerPort: 80
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment-container
image: nginx
ports:
- containerPort: 80
차이점
- Deployment는 업데이트 하는 기능이 강화되었다.