220715

HyeonKi Jo·2022년 7월 15일
0
post-thumbnail

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 # 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의 삭제가 되지 않았다.
    -> 멀티큐브로 넘어간다.

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
    • 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는 빠르게 실습할 때 사용하고, 왠만해서는 실습 환경이라고 이 환경에서 사용하는것이 좋다.

Master 환경설정

  • 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 에 넣어, 재부팅해도 들어가도록 한다.

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		# 컨테이너포트를 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를 정리해준다.

ReplicaSet

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 두개씩 잘 분배되었다.

에러 1

  • 한 강의실에서 너무 많은 이미지 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 이제 레플리카셋을 올려준다.
  • 모두 러닝중이다.

에러 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

  • kubectl get svc
    • ClusterIP하나가 생겼다.

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는 업데이트 하는 기능이 강화되었다.
profile
Talking Potato

0개의 댓글