인프라/Docker&Kubernetes 2020. 7. 18. 23:12

 

오늘 다루어볼 포스팅은 "도커 이미지 만들기"이다. 이전에 한번 정리해야지해야지 하면서 미뤄왔었는데, 간단하게 다루어 볼것이다. 필자도 대충은 알았지, 뭔가 깊게 이해하지 못하고 이미지를 빌드했었는데, 이참에 기초부터 한번 정리해봐야겠다.

 

<Dockerfile 작성을 위한 인스트럭션>

 

 

1. FROM : 도커 이미지의 바탕이 될 베이스 이미지를 지정한다. Dockerfile로 이미지를 빌드할 때 먼저 FROM 인스트럭션에 지정된 이미지를 내려받는다. FROM에서 받아오는 도커 이미지는 도커 허브(Docker Hub)라는 레지스트리를 참조한다. 도커 특정 버전 이상에서는 Multi stage build가 가능해져서, 하나의 베이스 이미지(FROM ..)가 아닌 여러 베이스 이미지를 사용하여 빌드가 가능하다(FROM을 여러번 사용)

 

2. RUN : 도커 이미지를 실행할 때 컨테이너 안에서 실행할 명령을 정의하는 인스트럭션이다. 인자로 도커 컨테이너 안에서 실행할 명령을 그대로 기술한다.

 

3. COPY : 도커가 동작 중인 호스트 머신의 파일이나 디렉터리를 도커 컨테이너 안으로 복사하는 인스트럭션이다.

 

4. CMD : 도커 컨테이너를 실행할 때 컨테이너 안에서 실행할 프로세스를 지정한다. 2번의 RUN 인스트럭션은 이미지를 빌드할 때 실행되고, CMD는 컨테이너를 시작할 때 한 번 실행된다.

 

"> go run  /echo/main.go"를 CMD 인스트럭션에 기술하면 아래와 같다.
CMD ["go", "run", "/echo/main.go"]

 

5. ENTRYPOINT : CMD와 마찬가지로 컨테이너 안에서 실행할 프로세스를 지정하는 인스트럭션이다. ENTRYPOINT를 지정하면 CMD의 인자가 ENTRYPOINT에서 실행하는 파일(셸 등)에 인자로 전달된다. 즉, ENTRYPOINT에 지정된 값이 기본 프로세스를 지정하는 것이다.

 

FROM golang:1.10

#./entry.sh을 실행시키면서 ARG1, ARG2를 entry.sh의 인자로 전달한다.
ENTRYPOINT ["./entry.sh"]
CMD ["ARG1", "ARG2"]

 

6. LABEL : 이미지를 만든 사람의 이름 등을 적을 수 있다.

 

7. ENV : 도커 컨테이너 안에서 사용할 수 있는 환경변수를 지정한다.

 

8. ARG : 이미지를 빌드할 때 정보를 함께 넣기 위해 사용한다. 이미지를 빌드할 때만 사용할 수 있는 일시적인 환경변수다.

 

 

posted by 여성게
:
인프라/Docker&Kubernetes 2020. 6. 4. 17:10

이번 포스팅은 간단하게 싱글 노드 카프카를 도커로 띄우는 방법이다.

 

git clone https://github.com/wurstmeister/kafka-docker
cd kafka-docker

 

설정 파일은 docker-compoese로 되어있으며, 아래와 같다.

 

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka:
    build: .
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
      KAFKA_CREATE_TOPICS: "test:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

 

docker compose 명령으로 실제 컨테이너를 띄운다.

 

docker-compose -f docker-compose-single-broker.yml up -d

 

posted by 여성게
:
인프라/네트워크(기초) 2020. 4. 22. 23:41

 

오늘 다루어볼 내용은 DNS Record type중에 A record와 CNAME의 차이점을 간단하게 다루어본다.

 

A record

DNS의 레코드 타입중에 A record type이란 간단하게 도메인(domain) name에 IP Address를 매핑하는 방법이다.

 

> nslookup coding-start.tistory.com
Server:		10.20.30.60
Address:	10.20.30.60#53

Non-authoritative answer:
Name:	coding-start.tistory.com
Address: 211.231.99.250

 

위 nslookup <domain> 명령을 치면 211.231.99.250이라는 IP가 매핑되어 있는 것을 볼 수 있다. IP 매핑은 VIP로 매핑하여 여러 IP를 하나의 도메인에 매핑할 수도 있고, A 타입 레코드에 각 서버의 IP를 여러개 넣을 수도 있다.

 

#VIP?
VIP는 하나의 호스트에 여러 개의 IP주소를 할당하는 기술이다. 이 기술을 이용하면, 
하나의 네트워크 인터페이스에 여러 개의 IP 주소를 줄 수 있다. 
바깥에서는 마치 하나 이상의 네트워크 인터페이스가 있는 것으로 보일 것이다. 
VIP는 흔히 HA나 로드밸런싱을 위해서 널리 사용된다.

vip : 211.231.99.250
ip list : a.b.c.d, d.a.e.s, d.e.a.h, d.e.a.a ...

 

CNAME(Canonical Name)

 

Canonical Name의 줄임말로 하나의 도메인에 도메인 별칭을 부여하는 방식이다. 즉, 도메인의 또 다른 도메인 이름으로 생각하면 좋을 것 같다.

 

coding-start.com -> coding-start.tistory.com (CNAME)
coding-start.tistory.com -> 211.231.99.250 (A record)

 

A record는 직접적으로 IP가 할당되어 있기 때문에 IP가 변경되면 직접적으로 도메인에 영향을 미치지만, CNAME은 도메인에 도메인이 매핑되어 있기 때문에 IP의 변경에 직접적인 영향을 받지 않는다.

 

여기까지 간단하게 A record와 CNAME의 차이점을 알아보았고, 혹시나 DNS record의 여러가지 type을 보고 싶다면 아래 위키 페이지를 참조하자.

 

 

List of DNS record types - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search This list of DNS record types is an overview of resource records (RRs) permissible in zone files of the Domain Name System (DNS). It also contains pseudo-RRs. Resource records[edit] Ty

en.wikipedia.org

 

posted by 여성게
:
인프라/Docker&Kubernetes 2020. 4. 21. 11:43

이번 포스팅에서 다루어볼 내용은 DOOD로 도커를 띄웠을 때, proxy 설정하는 방법이다. 그전에 간단하게 Docker in Docker(dind)와 Docker Out Of Dcoker(DooD)에 대해 알아보자.

 

Docker in Docker(dind)

도커 내부에 격리된 Docker 데몬을 실행하는 방법이다. CI(Jenkins docker agent) 측면에서 접근하면 Agent가 Docker client와 Docker Daemon 역할 두가지를 동시에 하게 된다. 하지만 이 방법은 단점이 존재한다. 내부의 도커 컨테이너가 privileged mode로 실행되어야 한다.

 

> docker run --privileged --name dind -d docker:1.8-dind

 

privileged 옵션을 사용하면 모든 장치에 접근할 수 있을뿐만 아니라 호스트 컴퓨터 커널의 대부분의 기능을 사용할 수 있기 때문에 보안에 좋지않은 방법이다. 하지만 실제로 실무에서 많이 쓰는 방법이긴하다.

 

Docker out of Docker(dood)

Docker out of Docker는 호스트 머신에서 동작하고 있는 Docker의 Docker socket과 내부에서 실행되는 Docker socket을 공유하는 방법이다. 간단하게 볼륨을 마운트하여 두 Docker socket을 공유한다.

 

> docker run -v /var/run/docker.sock:/var/run/docker.sock ...

 

이 방식을 그나마 Dind보다는 권장하고 있는 방법이긴하다. 하지만 이 방식도 단점은 존재한다. 내부 도커에서 외부 호스트 도커에서 실행되고 있는 도커 컨테이너를 조회할 수 있고 조작할 수 있기 때문에 보안상 아주 좋다고 이야기할 수는 없다.

 

DooD proxy 설정

dood로 도커를 띄운 경우, 호스트 머신에 동작하고 있는 도커에 proxy 설정이 되어있어야 내부 도커에도 동일한 proxy 설정을 가져간다.

 

방법1. /etc/sysconfig/docker에 프록시 설정
> sudo vi /etc/sysconfig/docker
HTTP_PROXY="http://proxy-domain:port"
HTTPS_PROXY="http://proxy-domain:port"

#docker restart
> service docker restart

 

방법2. 환경변수 설정
> mkdir /etc/systemd/system/docker.service.d
> cd /etc/systemd/system/docker.service.d
> vi http-proxy.conf

[Service]
Environment="HTTP_PROXY=http://proxy-domain:port"
Environment="HTTPS_PROXY=http://proxy-domain:port"
Environment="NO_PROXY=hostname.example.com, 172.10.10.10"

> systemctl daemon-reload
> systemctl restart docker

> systemctl show docker --property Environment
Environment=GOTRACEBACK=crash HTTP_PROXY=http://proxy-domain:port HTTPS_PROXY=http://proxy-domain:port NO_PROXY= hostname.example.com,172.10.10.10

 

여기까지 dood로 도커 엔진을 띄웠을 때, proxy 설정하는 방법이다.

 

 

참고

 

How to configure docker to use proxy – The Geek Diary

 

www.thegeekdiary.com

 

posted by 여성게
:
인프라/Docker&Kubernetes 2020. 4. 20. 21:48

공식 dockerhub가 아닌, 개인 혹은 사내 dockerhub로 push하는 방법이다. (dockerHubHost가 개인 혹은 사내 도커허브 도메인)

 

> docker build -t dockerHubHost/levi.yoon/jenkins_example
> docker push dockerHubHost/levi.yoon/jenkins_example

 

뭔가 다른 방법이 있을 것 같긴한대.. 간단하게 위 방법으로도 가능하다 !

posted by 여성게
:
인프라/네트워크(기초) 2020. 4. 12. 15:57

 

필자는 그동안 프록시서버와 게이트웨이를 혼동해서 용어를 많이 사용했었던 것 같다. 사실 글을 쓰는 지금까지도 이 두개의 차이점을 100% 명확히 구분짓기 힘들지만, 범용적으로 사용되는 프록시서버와 게이트웨이를 뜻을 알아본다.

 

Proxy Server(프록시 서버)

위키에는 프록시 서버에 대한 설명이 아래와 같이 나와있다.

 

프록시 서버 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다. 서버와 클라이언트 사이에 중계기로서 대리로 통신을 수행하는 것을 가리켜 '프록시', 그 중계 기능을 하는 것을 프록시 서버라고 부른다.
프록시 서버 중 일부는 프록시 서버에 요청된 내용들을 캐시를 이용하여 저장해 둔다. 이렇게 캐시를 해 두고 난 후에, 캐시 안에 있는 정보를 요구하는 요청에 대해서는 원격 서버에 접속하여 데이터를 가져올 필요가 없게 됨으로써 전송 시간을 절약할 수 있게 됨과 동시에 불필요하게 외부와의 연결을 하지 않아도 된다는 장점을 갖게 된다. 또한 외부와의 트래픽을 줄이게 됨으로써 네트워크 병목 현상을 방지하는 효과도 얻을 수 있게 된다.

 

HTTP Protocol 관점에서 조금 더 설명을 더하자면, 프록시 서버는 클라이언트와 서버 사이에 위치하여, 클라이언트의 모든 HTTP 요청을 받아 서버에 전달한다.(대개 요청을 수정한 후에) 이 애플리케이션(프록시서버)은 사용자를 위한 프록시로 동작하며 사용자를 대신해서 서버에 접근한다. 프록시는 주로 보안을 위해 사용된다. 즉, 모든 웹 트래픽 흐름 속에서 신뢰할 만한 중개자 역할을 한다. 또한 프록시는 요청과 응답을 필터링한다. 예를 들어 회사 내부망에서 외부로 요청(메이븐, 그래들 라이브러리 다운로드 등)을 신뢰할만한 요청인지 확인해서 회사 내부정책에서 인정한 인가한 서버만 접속가능하도록 하는 등의 기능이다.

 

밑은 용도에 따른 Proxy server 종류이다.

  • Caching Proxy Server : 이전 클라이언트의 요청 내용과 응답 컨텐츠를 저장해 두었다가 동일한 요청이 들어오면 저장된 컨텐츠를 전송한다. 이 방법을 이용하면 높은 트래픽에 대한 대응이 가능하다. 비용 절감 효과도 있을 수 있기 때문에 Caching Proxy를 자주 사용한다.
  • Web Proxy : 웹 트래픽에 초점이 맞춰진 Proxy 서버이다. 가장 일반적인 형태를 Web Cache이다. 어떤 프록시 서버는 이기종간의 컨텐츠를 변환하는 일을 하기도 한다.
  • Forward Proxy : 일반적으로 사용하는 프록시 방식이다. 프록시 서버는 클라이언트와 애플리케이션 서버사이에 위치하여 클라이언트가 타겟인 서버에 애플리케이션 서비스를 요청할 때, 프록시 서버로 요청을 보내게 된다. 프록시서버는 그 사이에서 중계자 역할을 하게된다.(애플리케이션 서버에게 클라이언트가 누구인지 감춰진다.)
  • Reverse Proxy : 기본적인 구성은 Forward Proxy와 동일하지만, 클라이언트는 Proxy Server 뒤에 있는 타겟서버의 URL이 아닌 Proxy Server의 URL로 요쳥한다. 이를 통해 애플리케이션 서버는 외부로부터 감춰지는 효과를 보게된다.(클라이언트에게 애플리케이션 서버가 무엇인지 감춰진다.)

 

우리가 많이 사용하는 Nginx 같은 녀석도 프록시서버라고 볼수도 있겠다. Nginx는 위에서 설명한 대부분의 기능을 모두다 제공한다.(캐시, 포워드 프록시, 리버스 프록시)

 

Gateway(게이트웨이)

 

위키에는 게이트웨이 서버를 아래와 같이 설명한다.

 

게이트웨이는 컴퓨터 네트워크에서 서로 다른 통신망, 프로토콜을 사용하는 네트워크 간의 통신을 가능하게 하는 컴퓨터나 소프트웨어를 두루 일컫는 용어, 즉 다른 네트워크로 들어가는 입구 역할을 하는 네트워크 포인트이다. 넓은 의미로는 종류가 다른 네트워크 간의 통로의 역할을 하는 장치이다. 또한 게이트웨이를 지날 때마다 트래픽(traffic)도 증가하기 때문에 속도가 느려질 수 있다. 쉽게 예를 들자면 해외여행을 들 수 있는데 해외로 나가기 위해서 꼭 통과해야하는 공항이 게이트웨이와 같은 개념이다.
즉, 게이트웨이는 서로 다른 네트워크 상의 통신 프로토콜(protocol,통신규약)을 적절히 변환해주는 역할을 한다.

 

게이트웨이는 프록시 서버와 비슷하게 클라이언트(혹은 서버)와 서버끼리 통신 사이에 중개자로 동작하는 서비스이다. 하지만 용도가 조금 다르다. 게이트웨이는 주로 HTTP 트래픽을 다른 프로토콜로 변환하기 위해 사용한다. 마치 게이트웨이는 언제나 스스로가 리소스를 갖고 있는 진짜 서버인 것처럼 요청을 다룬다. 클라이언트는 자신이 게이트웨이와 통신하고 있음을 알아채지 못할 것이다.

 

두 컴퓨터가 네트워크 상에서 서로 연결되려면 동일한 통신 프로토콜을 사용해야 하는데, 만약 요청은 HTTP 요청이고 백엔드에서 데이터를 가져오려면 FTP 통신이 필요하다면 중간에 게이트웨이가 두 프로토콜을 호환가능하도록 HTTP->FTP, FTP->HTTP를 대신 해주는 대행자가 되는 것이다.

 

Gateway(게이트웨이)

각각의 의미가 무엇이며 용도에 대해 알아보니 둘의 차이점을 조금이나마 알수 있었다. 둘다 중개자 역할임은 동일하지만 각각의 용도가 다르다는 것을 차이점으로 볼 수 있을 것 같다.

 

프록시 서버는 컨텐트 캐시, 보안, 필터링 등의 역할을 하는 중개자라면 게이트웨이는 서로 다른 네트워크 통신에서 서로 다른 프로토콜을 호환가능하게 하는 특별한 서버라고 볼 수 있을 것 같다.

 

여기까지 간단하게 프록시서버와 게이트웨이 서버가 무엇인지 둘의 차이점을 다루어보았다.

posted by 여성게
:
인프라/Docker&Kubernetes 2020. 4. 9. 17:00

 

Dockerfile 파일이 아니라, 커스텀한 파일명으로 docker manifest를 작성하였을 때, 로컬 빌드하는 명령이다. Dockerfile로 작성되어 있을 때 로컬빌드 명령은 아래와 같다.

 

docker build -t 1223yys/web-project:latest .

 

만약 Dockerfile이 아닌 다른 파일명으로 image manifest를 작성하였을 때는 아래와 같다.

 

docker build -t 1223yys/web-project -f ./custom_file_name .

 

위 명령을 실행한 후에 이미지가 잘 빌드되었는지 확인해보자.

 

docker image ls
posted by 여성게
:
인프라/네트워크(기초) 2020. 4. 7. 11:55

오늘 살펴볼 내용은 GSLB(Global Server Load Balancing)이다. 간단하게 GSLB가 뭔지, 일반 DNS서비스와 어떠한 점이 다른지 등을 살펴보자

 

GSLB(Global Server Load Balancing

이름만 보면 얼핏 업그레이드된 로드 밸런싱 형태라고 생각할 수 있지만, 이름과는 다르게 DNS 서비스의 발전된 형태이다.(물론 LB 역할을 하긴 하지만 근본적으론 DNS형태라 보면 좋을 것 같다.)

 

DNS는 도메인 주소와 IP를 매핑하여 도메인으로 요청이 들어왔을 때 타켓의 주소로 변환해 주는 서비스이다. 하나의 도메인 주소에 대해서 여러 개의 IP주소를 넘겨 줄 수 있는데, 이 기능을 이용해서 가용성 구성과 로드 밸랜싱 기능을 수행하기도 한다. DNS 뒤에 여러 IP를 붙여 고가용성과 로드 밸런싱 역할을 할 수 있긴 하겠지만 근본적으로는 한계가 있다.

 

그 이유는 DNS의 로드 밸런싱은 IP 목록중 하나를 반환할 뿐(라운드로빈?) 네트워크 지연, 성능, 트래픽 유입, 서비스 실패 등은 전혀 고려하지 않는다. 

 

이러한 문제를 해결하기 위해 나온 것이 GSLB이다.

 

GSLB & DNS 동작방식 차이

1. 재해복구

<DNS>

 

 

 

DNS는 서버의 상태를  알 수 없기 때문에 서버시를 실패하는 유저들이 다수 존재한다.

 

<GSLB>

 

 

 

GSLB는 서버의 상태를 모니터링 하기 때문에 실패한 서버의 IP는 응답(Converting Domain to IP response) 에서 제외하므로, 유저는 서비스를 계속해서 이용할 수 있다. 물론 어떠한 상황이냐에 따라 응답에 실패하는 경우가 존재할 것이다.

 

2.로드밸런싱

<DNS>

 

 

 

위에서 간단히 설명한 것과 같이 DNS는 Round Robin 방식으로 로드밸런싱한다. 즉, 정교한 로드밸런싱이 불가능하다. 작은 서비스는 크게 문제 없겠지만 트래픽이 아주 높은 서비스 같은 경우는 정교한 로드 밸런싱이 필요하다.

 

<GSLB>

 

 

 

GSLB는 서버의 로드(상태)를 모니터링하기 때문에 트래픽이 몰리지 않은 서버의 IP를 반환해주기 때문에 DNS보다 정교한 로드밸런싱이 가능하다.

 

3.레이턴시 기반

<DNS>

 

 

 

DNS는 Round Robin 방식을 사용하기 때문에 유저는 자신이 위치한 곳과 아주 먼곳에 떨어진 서버로 연결이 될 수도 있다.(물론 글로벌하지 않은 서버는 서버가 모여있기는 하지만..뭐)

 

<GSLB>

 

 

 

GSLB는 각 지역별로 서버에 대한 레이턴시(latency) 정보를 가지고 있기 때문에 해당 유저로부터 레이턴시가 적은 서버의 IP를 반환해준다.

 

4.위치 기반

<DNS>

 

 

 

DNS는 Round Robin 방식으로 서버에 연결된다.

 

<GSLB>

 

 

 

GSLB는 유저의 지역정보를 기반해서 가까운 지역의 서버로 연결 하게 한다.

 

GSLB의 주요 기능

1. Healthcheck

GSLB는 등록된 호스트들에 대해서 주기적으로 Health check 요청을 보내기 때문에, Health check가 실패한 서버는 DNS 응답에서 해당 서버를 제외한다. 실패한 서버에 대한 접근을 사전 차단하기 때문에 사전에 장애 방지가 가능하고, 사용자로 하여금 서비스 실패 확률을 낮춰준다.

 

2. 네트워크 거리 & 지역

주기적으로 성능을 측정하고 그 결과를 저장하기 때문에 DNS 요청이 오면 지리적으로 가까운 서버를 반환하거나 네트워크 거리가 가까운 서버를 반환한다. 지리적으로 가까운 서버의 경우 RTT(Round Trip Time)도 짧기 때문에, 동일한 결과를 반환하는 경우가 많다.

 

3.상세 작동 프로세스

<DNS>

 

 

 

<GSLB>

 

 

 

작동 방식은 세부적으로 살펴보면 많은 점이 다를 수 있겠지만 크게 IP를 선택하는데 있어서 GSLB Policy에 따라 어떤 IP를 반환할지 결정하는 부분이 존재하는 것이다. 위와 같이 위치기반, 레이턴시 기반 등의 정책을 거쳐 선택이 될 수도 있고 혹은 Admin이 설정한 정책에 따라 선택이 될수도 있다.

 

서비스 로직

  1. 사용자가 www.example.com에 접속하기 위해 Local DNS 서버로 DNS Query를 보내고, Local DNS 서버는 Root DNS, .com DNS 서버를 거쳐
  2. GSLB로 www.example.com에 대한 DNS Query를 보냅니다.
  3. GSLB는 DNS Proxy로 동작하며, 따라서 이 DNS Query를 그대로 example.com DNS 서버로 전달합니다.
  4. example.com DNS 서버는 www.example.com에 대한 IP 주소(SLB의 Virtual IP) 1.1.1.1과 2.2.2.2가 미리 등록되어 있어 그 값을 GSLB로 전달해 줍니다. 전달 시 TTL은 300초라고 가정하겠습니다.
  5. GSLB는 나름의 정책(뒤에서 설명)을 통해 1.1.1.1과 2.2.2.2 중에 사용자를 위한 최적의 사이트를 결정하고 또한 TTL을 작은 값으로 변경(예. 10초)합니다. TTL 값 변경은 Local DNS 서버가 바인딩 정보(www.example.com에 대한 IP 주소)를 최소 시간 동안만 캐싱하게 하기 위함입니다. 
  6. GSLB의 정책(GSLB Policy)을 통해 결정된 웹서버 IP 1.1.1.1(혹은 IP 주소 리스트의 순서를 바꿔 1.1.1.1, 2.2.2.2로)과 변경된 TTL 값이 Local DNS로 전달되고,
  7. Local DNS는 사용자 단말에게 그 값을 전달합니다.
  8. 이제 사용자는 www.example.com의 IP 주소 1.1.1.1을 목적지로 하여 한국 사이트 SLB1으로 HTTP GET을 보내고, SLB1은 다시 나름의 정책(서버 Health/Load 등 고려)을 적용하여 최종 서버인 10.1.1.10으로 HTTP GET 메시지를 전달합니다.

 

GSLB Policy

 

 

 

 

여기까지 간단하게 GSLB에 대해 다루어보았다.

 

<참고>

GSLB - Global server Load Balancing

GSLB와 DNS 작동방식 비교

www.joinc.co.kr

 

posted by 여성게
: