2024.04.21

 

공유기: 라우터 + 스위치 

외부에서 내부로 들어올 때 NAT (공인에서 사설IP로) Router

서로 다른 네트워크의 통신 그러니까 서로 다른 랜들끼리 통신하기 위해 라우터 사용 

 

 

컨테이너 만들 때 할당된 IP 172.17.0.𝒙 

 

172.17.0.1은 Bridge 

  • Docker의 기본 Bridge 네트워크의 게이트웨이 주소: 172.17.0.1 
  • Docker는 Host System과 독립적인 네트워크 환경을 가지는데, 컨테이너가 생성될 때마다 Docker는 Host system과 연결된 Bridge Network 생성한다
  • 이 네트워크의 게이트웨이 주소가 172.17.0.1 로 설정
  • 호스트 시스템에서 컨테이너에 접근하기 위한 게이트웨이 역할 

 

∴ Docker가 관리하는 네트워크에서 컨테이너의 IP 주소: 172.17.0.𝒙

Host system에서 172.17.0.1을 통해 컨테이너에 접근가능 

 

Ubuntu: Local Host 

 


 

🐋컨테이너간 통신 (네트워크) 

 

Q1. 컨테이너는 어떻게 통신?

Q2. 컨테이너 포트는 외부로 노출 가능?

Q3. 컨테이너 네트워크 추가 가능?

Q4. 컨테이너끼리 통신 어떻게? 

 

 

 

Q1. 컨테이너는 어떻게 통신?

원래 다른 랜끼리는 통신 안됨 (보면 IP 충돌)

이를 CNI 를 통해서 통신하게끔 설정한다 

 

 

  • Container Network Model
  • docker 0
    • Virtual Ethernet bridge: 172.17.0.0 /16
    • L2 통신 기반 
    • 컨테이너 생성 시 veth 인터페이스 생성 (sandbox)
    • 모든 컨테이너는 외부 통신을 docker0을 통해 진행
    • Container running 시 172.17.𝒙.𝒚 로 IP 주소 할당 

 

#docker network ls 

host only network: host 끼리만 통신

Bridge: NAT 역할 그러니까 docker 0

 

1. lo <LOOPBACK>

2. enp0s: 사진에서 eth0 (host1) 

3. docker0: 사진에서 bridge 

컨테이너와 로컬 호스트 간의 가교 역할이 docker0(bridge) 

외부와 통신할 때도 veth0과 1과 통신할 때도 docker0가 있어야 한다 

 

 

Q2. 컨테이너 포트 노출 

Port-Forwarding

 

  • Container Port를 외부로 노출시켜 외부 연결 허용
  • iptables rule을 통한 포트 노출
    • -p hostPort:containerPort 
    • -p containerPort
    • -p
  • $docker run --name web -d -p 80:80 nginx:1.14
    • -p 80:80에서 host port가 사진에서 eth0
    • 뒤에 container port는 사진에서 veth0 
    • * 3306이 mysql(DB) port

 

  • $iptables -t nat -L -n -v 

#iptables -t nat -L -n -v

Chain DOCKER 아래에

DNAT tcp dpt:80 to:172.17.0.2:80 보임 

 

 

 

Q3. 컨테이너 네트워크 추가 

 

 

user-defined bridge network 생성 

$docker network create --driver bridge \

--subnet 192.168.100.0 /24 \

--gateway 192.168.100.254 \

mynet

$docker network ls

 

$docker run -d --name web -p 80:80 nginx:1.14

$curl localhost

 

$docker run -d --name appjs --net mynet --ip 192.168.100.100 -p 8080:8080 \

[hub.docker.com ID 입력]/appjs

-p 8080:8080 \ 아래에

powermvp(선생님 hub.docker.com ID) 

 

$curl localhost:8080 

# 

 

 

 

 

Q4. 컨테이너끼리 통신 

 

컨테이너를 이용한 Server & Client 서비스 운영 

 

#docker run -d --name mysql -v /dbdata:/var/lib/mysql -e MYSQL_ROOTPASSWORD=wordpress -e

MYSQL_PASSWORD=wordpress mysql:5.7

 

#docker run -d --name wordpress --link mysql:mysql -e WORDPRESS_DB_PASSWORD=wordpress -p 80:80 wordpress:4 

# 

 

 


 

Docker Network 

개요

도커 네트워크 구조

컨테이너 포트 노출

expost vs Publish 

도커 네트워크 드라이버 

 


 

도커 네트워크 구조

veth: Virtual eth

docker0: 도커 엔진에 의해 기본 생성되는 브릿지 네트워크

⇒ veth와 eth 간 다리 역할 

host running docker

 

#ifconfig로 확인 

 

 

 

컨테이너 포트 노출 

컨테이너의 포트를 호스트의 IP:PORT와 연결하여 서비스를 노출

$docker run -p [HOST IP:PORT] : [CONTAINER PORT] [container]

 

#nginx 컨테이너의 80번 포트를 호스트 모든 IP의 80번 포트와 연결하여 실행

$docker run -d -p 80:80 nginx

 

#nginx 컨테이너의 80번 포트를 호스트 127.0.0.1 IP의 80번 포트와 연결하여 실행

$docker run -d -p 127.0.0.1:80:80 nginx 

 

#nginx 컨테이너의 80번 포트를 호스트의 사용 가능한 포트와 연결하여 실행

$docker run -d -p 80 nginx 

 

# nginx 컨테이너 포트 랜덤하게 

$docker run -d -P nginx

#

 

포트번호를 뒤에 주지 않고 -P 옵션으로 만들어서 확인해보면

32768로 랜덤하게 포트가 할당 

 

 

Expose VS Publish

#expose 옵션은 그저 문서화 용도

$docker run -d --expose 80 nginx

 

#publish 옵션은 실제 포트를 바인딩

$docker run -d -p 80 nginx

여기서 -p는 publish의 약자 

 

 

 

도커 네트워크 드라이버 

docker ls 로 치면

bridge, host, none이라고 뜬다 

 

Multi host networking은 클러스터 구성할 때 

 


 

Dockerfile 이용하여 이미지 생성

Dockerfile 기반으로 새 이미지 생성 가능

파일을 가지고 빌드하려면 -f 옵션을 준다 

$docker build -t [이름]:버전 -f [이미지 빌드] 

#docker build [OPTIONS] PATH

# ./ 디렉토리를 빌드 컨텍스트로 my_app:v1 이미지 빌드 (Dockerfile 이용)

$docker build -t my_app:v1 ./

 

# ./ 디렉토리를 빌드 컨텍스트로 my_app:v1 이미지 빌드 (example/MyDockerfile 이용)

$docker build -t my_app:v1 -f example/MyDockerfile ./

# 

 

 

 

.dockerignore 

.gitignore과 동일한 문법

특정 디렉토리 혹은 파일 목록을 빌드 컨텍스트에서 제외하기 위한 목적 

#comment

*/temp*

*/*/temp*

temp?

 

*.md

!README.md

# 

 

 

Dockerfile 문법

FROM node:12-alpine

RUN apk add --no-cache python3 g++ make

WORKDIR /app

COPY . .

RUN yarn install --produection

CMD ["node", "src/index"]

 

 


 

도커를 이용한 컨테이너 관리

#도커 이미지 다루기: 이미지 경량화 전략🌟

경량화가 정말 중요 

INDEX 

꼭 필요한 패키지 및 파일만 추가

컨테이너 레이어 수 줄이기 

↳ RUN의 갯수를 줄인다 

경량 베이스 이미지 선택

멀티 스테이지 빌드 사용 

 

 

 

docker-file.zip
1.69MB

 

docker-file.zip 을 풀어서 오른쪽의 Docker에 업로드한다 

 

#cd /home/guru 이동해서 

#cd docker-file 

 

#cd slacktee/

#vi Dockerfile

#cd..

#cd nodejs-server/

#ls로 Dockerfile로 시작하는 파일들 vi로 다 열기 

vi Dockerfile

RUN \

RUN의 횟수를 줄이기 위해 뒤에 &&를 넣는다 

--no-cache 넣어서 캐시들 삭제시켜주기 

 

그리고 docker build --force-rm -t  이부분 복사해서 

Dockerfile 로 시작하는 모든 파일들 이름대로 아래와 같이 paragraph(절) 메모장에 문장 만들어놓고 

docker build --force-rm -t nodejs-server .
docker build --force-rm -t nodejs-server:slim -f Dockerfile.slim .
docker build --force-rm -t nodejs-server:alpine -f Dockerfile.alpine .
docker build --force-rm -t nodejs-server:alpine-multi -f Dockerfile.alpine-multi . 

 

vi Dockerfile.slim

 

 

 

 

vi Dockerfile.alpine-multi

AS build

AS release나 위에서 썼던 코드를 그대로 사용하겠다

AS base 

 

FROM 절 뒤에 base AS 사용해서 Build 

멀티 뭐시기 build 

 

 

 

위에 paragraph(절)들 이렇게 붙여넣기 해서 다운 

 

#docker images로 확인해보면 

처음 916MB인 크기가 나중에는 120MB로 줄어든다 

그래서 기본이미지 사용하지 말고 이 경량화가 정말정말 중요!!!!!!! 

 

 

 

 


 

VirtualBox 파일 - 가상 시스템 내보내기

파일 경로 지정하고 

MAC 주소 정책: 모든 네트워크 어댑터 MAC 주소 포함 

이렇게 하고 기존에 있던 가상머신 삭제 

 

 

그리고 NEW docker IP를 105로 바꾸기 

docker install guide.pdf 파일 참고해서 Shell 에서 NEW Docker 패키지들 설치한다 

 

 

 

NEW docker를 k8s-master라는 이름으로 변경한다 

그리고 NAT Networks에 포트포워딩 탭에서 추가해줌 

 

#vi /etc/hosts열어서 

vi /etc/hosts

10.100.0.105 k8s-master로 변경 후 

#cat /etc/hosts로 확인 

 

 

#vi /etc/hostname으로 가서 

vi /etc/hostname

localhost를 k8s-master로 변경 

 

#vi /etc/hosts 편집 

vi /etc/hosts

10.100.0.106은 k8s-worker1

10.100.0.107은 k8s-worker2로 문장 추가 

 

 

 

 

기존에 있던 k8s-master (이름 변경전이라 docker이다) 중지시키고 복제한다 

 

 

 

아래와 같이 2개를 복제해서 생성 

총 3개가 만들어지면 된다 

 

 

k8s-worker1의 power on 

IP 주소 10.100.0.106 변경 

#ifconfig로 변경된 주소 확인 

#vi /etc/hostname 열어서 

vi /etc/hostname

k8s-worker1으로 변경한다 

 

#reboot 

 

 

k8s-worker2를 power on

IP 주소 10.100.0.107 으로 변경 

#vi /etc/hostname 들어가서 k8s-worker2로 변경 후 #reboot

※ 이 모든 건 root에서 작업 

 

 

 

🐚Shell로 가서 

복붙하고 

Name: k8s-worker1

host: 127.0.0.1 

port: 106

protocol: SSH

비밀번호까지 설정하고

 

하나 더 복붙해서 

k8s-worker2

127.0.0.1

107

SSH 비번까지 설정 후 

 

🐚Shell에서 ping test

ping 8.8.8.8

ping 10.100.0.106 / 107 / 105 

 

 

ping 통신 다 되면 VM VirtualBox로 가서 전부 다 power off 후 

파일 - 가상 시스템 내보내기 

 

 

 


 

모두의쿠버네티스.pdf
0.66MB

 

kubernetes install guide(20240415버전).pdf
0.16MB

PW: 12345ldcc!

 

클러스터를 만들어야 하기 때문에 workernode 3개를 만들어야 한다 

 

쿠버네티스 과정에 대한 강의 순서
수업내용
1. 쿠버네티스 시작
[1장] 소개 
[2장] 설치
[3장] 컨테이너 실행

2. 기본개념
쿠버 아키텍처
파드
컨트롤러
서비스
인그레스
레이블과 애너테이션
쿠버 dns
오토스케링
파드 스케줄링
인증과 권한관리
로깅과 모니터링 

 

 

쿠버 왜 사용

자동화된 빈 패킹 bin packing

한가로운 노드에 컨테이너를 생성한다 

컨테이너화된 작업 실행하는데 사용하는 쿠버네티스 클러스터 노드를 제공

각 컨테이너가 필요로 하는 CPU의 메모리RAM을 쿠버네티스에게 지시함

쿠버네티스는 컨테이너를 노드에 맞춰서 리소스를 잘 사용할 수 있도록 한다 

 

 

자동화된 복구 self-healing

만약 컨테이너가 5개 있는데 2개가 없어졌다면 자동적으로 2개를 만든다 

 

 

자동화된 롤아웃과 롤백 

버전이 1.1로 해뒀는데 1.2 버전이 있다면 알아서 롤아웃 롤백을 한다 

 

주요 설계 목표

컨테이너로 향상된 리소스 활용의 이점을 누림 + 복잡한 분산 시스템 쉽게 배포하고 관리 가능

 

쿠버네티스는 여러 개의 컨테이너화된 어플리케이션을 여러서버 (쿠버네티스 클러스터)에 자동으로 배포, 스케일링 및 관리해주는 오픈소스 시스템 

 

 

쿠버네티스 클러스터의 정의

클러스터: 여러 개의 서버를 하나로 묶은 집합, 하나의 서버처럼 동작

쿠버네티스 클러스터: 어플리케이션 컨테이너를 배포하기 위한 서버 집합 

 

 

 

 

Master 노드의 Control Plane

클러스터의 상태를 저장하고 관리

- etcd (key-value data store)

클러스터에 배포된 어플리케이션 실행 정보 저장

 

- API server

클러스터 상태 조회, 변경을 위한 API 인터페이스 제공

 

- Scheduler

- Controller Managers 

 

 

Worker 노드의 데이터 노드? 마스터 노드의 데이터 노드

컨테이너 실행 담당

- Kubelet, Container Runtime (Docker, ...)

- kube-proxy 

 

 

 

 

[1장] 쿠버네티스 소개

오케스트라의 지휘자 역할이라 조타수라고도 부른다 

컨테이너를 도커 플랫폼에 올려서 

관리 + 운영 + 클러스터 서비스까지 지원

= Container Orchestration

= kubernetes

= k8s 

 

웹 서버에 컨테이너 생성

 

 

클러스터의 기본동작

① 이미지를 빌드해 Docker hub에 push

② kubectl 명령어 실행해서 Kubernetes API 서버로 REST HTTP 욫어을 전달하고 클러스터에 새레플리케이션 컨트롤러 오브젝트 생성 

③ 레플리케이션 컨트롤러는 새 파드를 생성하고 스케줄러 (Scheduler)가 워커 노드 중 하나에 스케줄링 

④ 해당 워커 노드의 Kubelet은 파드가 스케줄링 된 것을 확인

⑤ 이미지가 로컬에 없기 때문에 Docker에게 레지스트리에서 특정 이미지를 pull 하도록 지시

⑥ 이미지 다운 후 Docker는 컨테이너를 생성하고 실행한다 

클러스터 기본동작

 

 

쿠버네티스 install guides.pdf 참고 

kubernetes install guide(20240415버전).pdf
0.16MB

 

마스터 노드는 무조건 2 CPU여야 설치가 된다 

 

 

[실행]1. kubelet 의 적절한 동작을 위해서 swap을 사용하지 않는다.

# swapon && cat /etc/fstab

# swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab

 

 

[실행]2. SELinux 와 방화벽을 해제한다.

# setenforce 0

# ufw disable (명령어 실행)

# systemctl stop firewalld

# systemctl disable firewalld

 

 

[실행]3. 모듈과 네트워크 파라미터가 영구적으로 적재되도록 파일에 편집

# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF 
> sudo sysctl --system

 

 

[확인]. 네트워크 파라미터 정보 변경 사항 확인

#  sysctl net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1

 

 

[실행]4. Update the apt package index and install packages needed to use the Kubernetes apt repository:

sudo apt-get update

sudo apt-get install -y apt-transport-https ca-certificates curl

 

 

[실행]5. 한줄한줄 명령어로 실행시킨다.

mkdir /etc/apt/keyrings

 

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

 

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

 

[확인]. Update apt package index, install kubelet, kubeadm and kubectl, and pin their version:

 

 

 

[실행]6. Install Kubernetes

sudo apt-get update

sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni

sudo apt-mark hold kubelet kubeadm kubectl

 

 

[실행]7. Configuring the kubelet cgroup driver

(https://kubernetes.io/docs/setup/production-environment/container-runtimes/)

cgroupfs를 컨테이너 런타임과 kubelet 에 의해서 제어할 수 있도록 구성한다.

#  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"
> }
> EO


 

sudo systemctl enable docker

sudo systemctl daemon-reload

sudo systemctl restart docker

 

 

[실행]8. 다음 아래 명령어를 순차적으로 입력 (master Node , Worker Node1, Node2 모두에서 실행)

sudo rm /etc/containerd/config.toml

sudo systemctl restart containerd

 

 

[실행]9. (마스터 노드에서만 실행) kubeadm init 명령을 통해서 클러스터를 생성한다.

#kubeadm init 하면 마지막 줄에 kubeadm join 구문이 나온다 

 

To start using your cluster, you need to run the following as a regular user:

root@k8s-master:~# mkdir -p $HOME/.kube
root@k8s-master:~# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@k8s-master:~# sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

 

[실행]10. 마스터 노드에서만 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  

 

 

[실행]11. 쿠버네티스 클러스터에 조인하기 위한 명령어 구문을 저장해둔다.

#cat > token.txt

하고 실행9번의 #kubeadm init해서 마지막에 나온 kubeadm join 10.100.0.105:6443 --token 72hg0z.1tfk45t4dl21me59 \
> --discovery-token-ca-cert-hash sha256:c11208bc6cb0571d4a741952ea74239575025b73b58eeabf6a4151bbb0c0f385
이걸복사해서 

붙여넣고 Ctrl D로 빠져나온다 

 

 

 

[실행]12. Pod가 서로 통신 할 수 있도록 CNI (Container Network Interface) 기반 Pod 네트워크 추가 기능 구성한다.

네트워크가 설치되기 전에 클러스터 DNS (CoreDNS)가 시작되지 않는다.

 

Master 노드에서만 실행 

#kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

 

#kubectl get nodes 보면 STATUS NotReady  

 

다시 확인해보면 STATUS Ready 

 

 

 

[실행]13. 워커 노드 양쪽에서 kubeadm join 구문을 실행한다

k8s worker 1, 2에도 kubeadm join 구문 복붙한다 

이때는 cat > token.txt 이거는 생략하고 init하고 나온 마지막 구문만 복붙한다 

 

내 노트북에선 

마지막 구문인 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

클러스터 되었다는 의미 

 

 

마스터에서 다시 kubectl get nodes로 확인해보면

세개 전부 다 ready로 나온다 

 

 

 

[실행]14. kubectl 자동명령어 실행 스크립트 

 

일단 master 계정에서만 실행함 

root@k8s-master:~# source <(kubectl completion bash)
root@k8s-master:~#  echo "source <(kubectl completion bash)" >>~/.bashrc
root@k8s-master:~#  source <(kubeadm completion bash)
root@k8s-master:~#  echo "source <(kubeadm completion bash)" >>~/.bashrc

 

그리고 마스터에서 다시 확인 

 

 

 

 


마스터 세션 복제하고 

 

 

세션 복제한거 우클릭 - 수평분할 

 

 

윗창에는 #watch kubectl get pods -o wide 

아래 창에 컨테이너와 이미지 만들면 바로 윗창에 만든게 보여진다 

#kubectl run web --image=nginx:1.14 --port 80

 

 

 

 

 

 

 

 

 

 

'☁︎클라우드 > 일자별' 카테고리의 다른 글

240422 DAY 73  (0) 2024.04.27
240419 DAY 72  (0) 2024.04.21
240417 DAY 70  (0) 2024.04.21
240416 DAY 69  (0) 2024.04.21
240415 DAY 68  (0) 2024.04.16