- 하나의 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 # desired state (kube-controller-manager) selector: matchLabels: app: nginx-replicaset # Selector의 라벨과, 아래 metadata의 라벨이 다르면 오류가 나게 된다. 레플리카셋의 스펙과, 컨테이너의 라벨이 연결되어야 제대로 동작하게 된다. 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의 삭제가 되지 않았다.
-> 멀티큐브로 넘어간다.
- 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
- docker를 시작프로그램에 등록
systemctl daemon-reload
- daemon-reload로 daemon(백그라운드실행)를 재부팅한다.
systemctl restart docker
- 도커 재실행
systemctl disable --now firewalld
- 방화벽을 꺼둔다.
setenforce 0
- selinux종료
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
- kernel에 적용해준다.
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
- kubelet을 시작프로그램에 등록한다.
복제
- VM을 poweroff하고, 연결된 복제로, Worker1~2를 만들어준다.
- 또, 원본 VM을 Master1으로 한다.
- master1은 2~3 등 늘어날 수 있다는 뜻이다.
- 이렇게 Master1, Worker1~2 총 3개의 VM이 생성되었다.
- Worker의 스펙은 CPU 1c, RAM 1Gb 로해준다.
- 또, 네트워크로 가서 MAC주소를 바꿔준다.
- 그룹을 만들어서 최종적으로 이 모습이 되도록한다.
- minikube는 빠르게 실습할 때 사용하고, 왠만해서는 실습 환경이라고 이 환경에서 사용하는것이 좋다.
- init이 끝나면 다른 worker들이 join할 수 있도록 명령어가 출력된다. 이를 메모장에 적어둔다.
mkdir -p $HOME/.kube
- 디렉토리를 하나 생성한다.
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- master의 자격증명을 꾸며 저장한다.
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 에 넣어, 재부팅해도 들어가도록 한다.
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 # 컨테이너포트를 8080으로 해본다.
kubectl apply -f nginx-pod.yaml
- pod를 실행한다.
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 정리
- pod과, service를 정리해준다.
vi replicaset.yaml
apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-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
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 두개씩 잘 분배되었다.
- 한 강의실에서 너무 많은 이미지 PUlling이 있어서 PUll이 막였다.
- 로그인을 해줘도 안되서 도커 사설 레지스트리를 설정하여 이미지를 공유한다.
마스터
docker pull nginx
- 마스터 서버에서 nginx를 pull 한다.
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
이제 레플리카셋을 올려준다.
- 모두 러닝중이다.
- 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"] }
apiVersion: v1
kind: Service
metadata:
name: clusterip-service-replicaset
spec:
type: ClusterIP
selector:
app: nginx-replicaset
ports:
- protocol: TCP
port: 80
targetPort: 80
kubectl get svc
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
kubectl delete -f replicaset.yaml
- 파일명으로도 pod을 지울 수 있다.
- 그러나 service들은 지워지지 않는다.
kubectl delete pod,svc --all
- 다 지운다.
- 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는 업데이트 하는 기능이 강화되었다.