리눅스데브코스 [16주차 - 3]<리눅스 컨테이너와 Docker (5) 실시간>

심우열·2023년 8월 10일
0

1. DOCKER의 다양한 운영 형태

  • 다중 호스트에서 Docker 컨테이너 운영
  • Docker 의 대안 솔루션
  • Swarm 과 K8S

2. Multiple Machine Docker 환경

  • VMWare 환경 이용
  • 2대 이상의 VM에서 실습 진행

1. VAGRANT로 VM 준비하기

  • VMWare Fusion 에서는 Vagrant 로 ip 지정이 안됨
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 
    config.vm.box = "bento/ubuntu-20.04-arm64"
    config.vm.provider "vmware_fusion" do |vw|
        vw.memory=2048
    end

    if Vagrant.has_plugin?("vagrant-vbguest")
        config.vbguest.auto_update = false
    end

    config.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: [".git/"]

    config.vm.provision "shell", inline: <<-SHELL
        export DEBIAN_FRONTEND=noninteractive
        sudo apt -y update
        sudo apt install -y ca-certificates curl gnupg libnss-mdns 
        sudo install -m 0755 -d /etc/apt/keyrings
        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
        sudo chmod a+r /etc/apt/keyrings/docker.gpg
        echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
        sudo apt -y update
        sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
        sudo usermod -aG docker vagrant
    SHELL

    config.vm.define "node01", primary: true do |node01| 
        node01.vm.hostname = "node01.local"
        node01.vm.network "private_network"#, ip: "192.168.33.101"
    end
    config.vm.define "node02" do |node02|
        node02.vm.hostname = "node02.local"
        node02.vm.network "private_network"#, ip: "192.168.33.102" 
    end
end

2. 두개 이상의 머신 관리하기

  • cluster shell을 이용한 관리
  • 관리하고 있는 모든 머신에 같은 명령어가 입력 될 수 있도록 해주는 툴

1. Cluster Shell 설치

관리 노드(머신)에서 설치

sudo apt -y update && sudo apt install -y clustershell

2. Cluster Shell 설정

1. 설정파일 위치

  • /etc/clustershell/

2. /etc/clustershell/groups.d/local.cfg 수정

# 모두 삭제 후 다음과 같이 작성 
all: node[01-02].local 
docker: node[01-02].local 
node: node[01-02].local

3. 각 머신에 PUBLIC 키 SSH 인증 등록

1. 관리 노드(머신) ssh-keygen

2. id_rsa.pub 내용 복사하기

cat ~/.ssh/id_rsa.pub

3. 복사한 id_rsa.pub 를 authorized_keys에 등록

echo "ssh-rsa ... ... " >> ~/.ssh/authorized_keys

4. 관리하고자 하는 다른 머신에 복사한 id_rsa.pub 를 authorized_keys에 등록

  • node02에서
echo "ssh-rsa ... ... " >> ~/.ssh/authorized_keys

4. 키 인증 연결 확인

  • 관리 노드에서 진행

1. node01(관리 노드)

ssh node01.local

1. node02

ssh node02.local

5. Clush 로 각 노드 명령어 전달 확인

clush -a ls -lah

  • node01 과 node02에 모두 명령어가 전달되어 결과가 출력됨
clush -w @docker docker ps

  • /etc/clustershell/groups.d/local.cfg 에 명시한 docker 그룹인 node01 과 node02에 모두 명령어가 전달되어 결과가 출력됨

3. 레지스트리 캐쉬 설정

1. daemon.json 작성

nano ~/daemon.json
# daemon.json
{
	"registry-mirrors": ["http://192.168.95.155:5000"], 
	"insecure-registries": ["192.168.95.155:5000"]
}
  • 192.168.95.155: 레지스트리가 존재할 노드의 IP주소
  • 5000: 레지스트리 포트번호

2. daemon.json 모든 노드에 복사

clush -a --copy ~/daemon.json
  • --copy 는 모든 노드의 같은 위치에 복사

3. daemon.json 설치

1. 각 노드에서 /etc/docker/daemon.json 에 복사

clush -a sudo cp daemon.json /etc/docker/daemon.json

2. Docker 재시작

clush -a sudo systemctl restart docker

4. Docker 정보 확인

clush -a docker info

5. 레지스트리 설정: Node01

1. 레지스트리 설정 파일 생성

mkdir -p /etc/docker/registry
sudo nano /etc/docker/registry/config.yml

2. 레지스트리 설정 파일 작성

# /etc/docker/registry/config.yml
version: 0.1 
storage:
  filesystem:
    rootdirectory: /var/lib/registry
  cache:
    blobdescriptor: inmemory
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
proxy:
  remoteurl: https://registry-1.docker.io

6. 레지스트리 실행: Node01

sudo docker run -d \
--restart unless-stopped \
-v /etc/docker/registry:/etc/docker/registry \ 
-p 5000:5000 \
--name registry \
registry:2

7. 레지스트리 테스트

clush -a docker pull 192.168.95.155:5000/library/registry:2

4. 컨테이너간 통신

  • 호스트가 같을 경우 컨테이너 간 통신 가능
  • 호스트가 다를 경우 컨테이너간 통신이 어려움
  • 서로 다른 호스트에서 컨테이너 생성시 할당되는 IP가 같기도 하고, 다른 호스트의 컨테이너와 통신도 안됨

1. 컨테이너간 통신 확인해보기

1. Node01-N1A

docker run -it --name N1A ubuntu
apt update
apt install -y iputils-ping iproute2
ip addr

2. Node01-N1B

docker run -it --name N1B ubuntu
apt update
apt install -y iputils-ping iproute2
ip addr

3. 핑 보내보기

ping 172.17.0.3

  • 같은 호스트상에서는 컨테이너 간 통신 됨을 확인 가능

2. 호스트가 다를때, 컨테이너간 통신 방법

1. 솔루션 사용

  • Weave
  • Flannel
  • Calico
  • ...

3. Weave 사용해보기

  • Network layer-2 지원
  • vxLan 지원

1. 기존 컨테이너 정리

clush -a docker system prune -af

Docker가 차지하는 공간 보는 방법

docker system df

2. Weave 사용하기

weave.works

1. Weave 설치하기

weave 설치 방법

clush -a sudo curl -L git.io/weave -o /usr/local/bin/weave
clush -a sudo chmod a+x /usr/local/bin/weave

2. Weave 실행하기

weave 실행 방법

1. 매니지 노드: Node01

weave lauch
eval $(weave env)

weave 컨테이너 생성 확인

docker ps

환경 변수 변경 확인

  • DOCKER_HOST가 weave.sock 으로 변경됨
env | grep -i docker

2. 게스트 노드: Node02, ...

clush에 게스트 노드들 등록해주기

  • /etc/clustershell/groups.d/local.cfg
  • peer 추가
all: node[01-02].local
docker: node[01-02].local
node: node[01-02].local
peer: node[02].local

게스트 노드에 대해 매니지 노드를 바라보게 weave 실행

clush -w @peer weave launch 192.168.95.155
clusg -w @peer eval $(weave env)

3. Weave 테스트(arm64 Ubuntu에서 안됨...)

1. 매니지 노드(node01)에서 a1 컨테이너 생성

  • 주의: eval $(weave env) 를 수행한 상태에서 해야함
docker run -it --name a1 weaveworks/ubuntu

2. 게스트 노드(node02, ...)에서 a2 컨테이너 생성

  • 주의: eval $(weave env) 를 수행한 상태에서 해야함
  • --rm: 프로세스 종료 시 컨테이너 자동 제거
docker run -it --rm --name a2 weaveworks/ubuntu

3. Weave를 사용하지 않는 컨테이너

eval $(weave env)

  • 이것을 실행하지 않으면, weave net을 사용 안함

이미 실행한 경우

eval $(weave env --restore)
  • 위 명령어를 실행해 원상 복귀 후 컨테이너 생성하기

4. 멀티 호스트 간 컨테이너 통신

CNI

  • Container Network Interface 설정하면 가능함

4. Docker Swarm

1. Swarm 이란?

Docker 에서 만든 Orchestration 도구

  • 컨테이너 배치 및 복제
  • 컨테이너 그룹에 대한 로드 밸런싱
  • 컨테이너 장애 복구, 호스트 머신에 대한 장애복구는 불가능
  • 클러스터 외부에 서비스 노출
  • 컨테이너의 확장/축소
  • 위 기능 외에 K8S의 기능과 거의 흡사함

2. Swarm 의 장점

  • 멀티 호스트의 Docker 들을 단일 가상 Host로 만들어줌
  • Docker와 Compose 명령을 그대로 사용 가능

3. 네트워크의 변화

1. 기존 네트워크

  • Bridge
  • Host
  • None

2. 새로 추가된 네트워크

Ingress: Overlay 타입

  • 여러 호스트에 걸쳐 구성하는 네트워크를 의미
  • Swarm 에 join 한 노드 내에서는 독립된 단일 네트워크 구성 가능

4. 볼륨 관리의 변화

1. docker run

  • --volume 또는 -v 로 지정

2. docker service

  • type=[TYPE]
    -> volume, bind, tmfps 중 하나
  • source=[SOURCE]
    -> 볼륨 이름 혹은 Host 의 경로
  • destination=[PATH]
    -> 컨테이너에서 경로

5. Swarm 구성하기

1. 매니지 노드에서

docker swarm init --advertise-addr 192.168.95.155

  • Node01을 Master(매니지 노드)로 하여 구성

2. 다른 노드에서

docker swarm join --token <TOKEN VALUE> 192.168.95.155:2377

3. 노드 그룹 확인

docker node ls

6. Swarm 용어

1. Node

  • 클러스터를 구성하는 개별 도커 호스트

2. Manager

  • 클러스터 관리와 컨테이너 오케스트레이션 담당
  • K8s의 Master 역할과 일치함

3. Worker

  • 컨테이너 기반 서비스들이 실제 구동되는 노드
  • Swarm 에서는 Manager 도 Worker로써 역할을 함께 수행

4. Stack

  • 하나 이상의 서비스로 구성된 다중 컨테이너
  • K8s의 POD과 다름

5. Service

  • 노드에서 수행하고자 하는 작업
  • 컨테이너 묶음 -> EndPoint 가 존재 함

6. Task

  • 서비스를 구성하는 개별 컨테이너
  • 실제 동작하는 컨테이너 - 복제 될 수 있음

7. 서비스 만들어 보기

1. Swarm으로 Service 생성

docker service create nginx

2. Service 목록 확인

docker service list

3. Service가 생성된 호스트

  • Node01 매니지 노드에서 서비스를 생성했지만,,
  • 서비스는 Node02 노드에서 생성됨

Swarm은 서비스를 분산시켜 생성함

4. Service 삭제

docker service rm <서비스 이름, ID>

5. 이름 있는 Service 생성

docker service create --name myweb nginx

6. Service 에 EndPoint Publish

docker service update --publish-add [포트 번호] myweb

어떤 호스트에서든 접근 가능

  • Node01
  • Node02

7. Service 복제하기

docker service update --replicas 2 myweb

Node01, Node02에 각각 하나씩 서비스가 생성됨

8. 서비스 축소하기

docker service update --replicas 1 myweb

9. Manual Port 개방하기

docker service create --name second_web --replicas 2 --publish published=8080,target=80 nginx
  • Manual Port(8080)으로 모든 노드에서 접근 가능

10. MODE

1. Replicated Mode

  • 서비스가 요청한 만큼 생성됨

2. Global Mode

  • 서비스가 모든 Worker에 1개씩 배치
  • 모니터링 요소에 적합한 모드

3. Node-Exporter 를 global로 배치해보기

docker service create --name=node-exporter --mode=global prom/node-exporter
  • 모든 worker에 Node-Exporter 서비스가 생성됨

11. 볼륨 추가하기

docker service create --name myweb3 --mount type=volume,source=html,destination=/usr/share/nginx/html nginx
  • Node02 에 서비스 생성됨
  • Node02 에 html 볼륨 생성됨

8. Swarm 과 Compose -> Stack

1. Docker Compose 작성

# docker-compose.yml
services:
  web:
    image: nginx
    depends_on:
      - db
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ahff

2. Swarm 으로 Compose 하기

docker stack deploy -c [docker-compose 파일] [Stack 이름]

5. PODMAN

1. PodMAN 이란?

POD MANAGER TOOL

  • OCI 표준 컨테이너
  • 런타임을 개발, 관리, 실행 할 수 있게 해주는 컨테이너 엔진

2. PodMAN 과 Docker 의 차이점

Daemon의 존재 여부

  • Docker 의 경우 Docker Daemon이 모든 작업을 처리
    -> Daemon에 문제가 있는 경우 작동 불가능
  • PodMAN 의 경우, 명령어에 대한 프로세스로 동작
    -> 명령어 실행때마다 새로운 프로세스를 만들기 때문에 ...
    -> 커널에 문제가 없는 한 계속 동작함

3. PodMAN 설치

  • CentOS:8 부터 기본지원
  • Ubuntu:20.04 부터 기본 지원

Ubuntu 20.04 는 Kubic 저장소 등록 후 사용

source /etc/os-release SRC=https://download.opensuse.org/repositories/devel:/kubic:/libcontainers $ echo "deb $SRC:/stable/xUbuntu_${VERSION_ID}/ /" \
	| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list 
curl -L $SRC:/stable/xUbuntu_${VERSION_ID}/Release.key \
	| sudo apt-key add -
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install podman

4. PODMAN 사용하기

1. docker 명령어로 podman 사용

alias docker=podman

2. docker 중지

sudo systemctl stop docker docker.socket
sudo systemctl disable docker

5. PODMAN 설정하기

/etc/containers/storage.conf

  • /run/containers/storage
    -> root로 사용됨(임시 저장 공간)
  • /var/lib/containers/storage
    -> 컨테이너의 읽기, 쓰기 가능한 레이어
profile
Dev Ops, "Git, Linux, Docker, Kubernetes, ansible, " .

1개의 댓글

comment-user-thumbnail
2023년 8월 10일

이런 유용한 정보를 나눠주셔서 감사합니다.

답글 달기