사설 도커의 ip를 알아보는 방법은 아직 없다.
사설 저장소 구축 참고
[Docker CE] Docker Private Registry 구축(Docker Registry, WEB 사용) :: Nirsa (tistory.com)
[Docker CE] Docker Private Registry 구축(Docker Registry, WEB 사용)
Private Registry는 개인 저장소라고도 하며 Docker hub에서 제공하는 registry 이미지를 사용 해 컨테이너에서 이미지를 로컬 저장하는 방식 입니다. 하지만 GUI 환경을 지원하지 않는데, Docker hub에 GUI로
nirsa.tistory.com
도커 허브 :
public
private 저장소 -> 그룹지정이 가능하여 그룹별로 접근 권한을 부여할 수 있다.
팀장이 올리고 개발자는 다운만 받아 사용
저장소 -> compose -> docker swarm -> docker stack (docker swarm + compose yml)
로컬저장소(=자체저장소) : 나만 접근가능한 저장소, 내가 찾고자하는 이미지가 있는지 확인해서 컨테이너 제작
만약 이미지가 없으면 docker hub에 연결
소프트웨어 개발을 위한 동일한 환경 구축을 위해 local 저장소에 이미지 구축 -> 이걸 공유하기 위한 저장소?
1. docker-hub
외부와의 연결차단
Docker Registry에 docker을 설치
프라이빗 네트워크 안의 Docker 레지스트리에 업로드 하려면 다음의 규칙을 사용하여 이미지에 태그를 붙여야 한다
docker image tag [로컬이미지명] [업로드할 레지스트리주소:포트번호]/[이미지명]
주소와 포트번호를 이용해 업로드를 한다.
그런데 이미지를 올리기 위해서는 인증이 필요하다.
하지만 우리는 컴퓨터가 많지 않은 상황이다.
뭐 대충 이렇게 사설저장소에 이미지를 올리고 push/pull을 하면된다.
내부 사설 엄데이트 주소를 구축해야하는 이유는
1. 속도 증대
2. 보안성 증대
떄문이다.
만약 이미지가 업데이트 되었다면 기존 이미지를 즉시 업데이트해준다.
---
사설 저장소 구축하기
```
docker image pull registry
docker container run -d -p 5000:5000 --name registry registry
```
하면 사설 저장소가 만들어진다.
먼저 centos를 이용해서 이미지를 만들어주자
```
docker image tag centos:7 localhost:5000/test:1.0
```
궁금해진게 이러면 매번 localhost나 ip를 이미지 앞에 적어주어야 하는데 꽤나 불편하다. 한번 hostname으로 파일을 만들어보자
```
docker image tag centos:7 docker01:5000/test:1.0
docker image push docker01:5000/test:1.0
```
일단 올려보자
하면 잘 올라간다.
올리기는 했는데 이게 올라갔는지 확인이 필요하다.
```
docker run -it -p 8080:8080 --name registry-web --link registry -e REGISTRY_URL=http://registry:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
```
정상 접근된다.
내가 올린 이미지가 있는 것을 확인할 수 있다.
그러니 이번에는 local저장소에서 이미지를 지워버리고 private 저장소에서 받아와보자
```
docker image pull docker01:5000/test:1.0
```
이미지가 잘 받아와진다.
로컬에 설치된 사설 저장소로 이미지를 pull/push 하는 것에는 인증관련 문제가 발생하지 않음.
단, 원격지(다른 서버)에서 로컬에 위치한 사설 저장소로 접속을 시도하거나. 내 서버에서 다른곳에 위치한 사설 저장소로 접속을 시도한다면 이는 https를 통한 접근이므로 인증서가 발급되어 있어야 접근할 수 있다. 하지만 현재 인증관련 내용이(설정되어 있지 않으므로) 없으므로 이미지를 pull, push 하는 것은 불가능하다.
인증을 거치지 않고 pull, push가 되도록 하고 싶다면 다음과 같이 진행한다.
```
systemctl stop docker
sudo vi /etc/default/docker
systemctl restart docker
```
위와같이 DOCKER_OPTS를 설정해주어서 인증서 없이도 접근가능하도록 만들면 된다.
위와같이 작성해주면 211.183.3.254라는 저장소 주소로 인증없이 접속. 이렇게 하면 인증없이 떨어진 주소에 이미지를 올릴 수 있게 된다.
외부에 있는 곳에 인증을 거치어서 들어가고 싶으면 아래의 방법을 쓰자
```
docker login 1.1.1.1 # 사설 저장소가 1.1.1.1에 구축되어 있고 ID/PW로 들어간다.
Username: test
Password:
```
인증이된다. 이게 되었다는 의미는 실재 로그인 되었다는 것이 아닌 우리의 ID/PW를 저장했다는 의미이다.
이렇게 하면 인증서버에서 ID/PW를 별도로 관리하겠다는 이야기이다.
정보 두개가 보이는데
1번은 우리가 등록한거다.(1.1.1.1) -> 인증서버로 가면 거기에 username/pw가 있는 경우이다.
2번의 주소는 docker hub를 등록한 것이다.
3번째 방법은 ID/PW 없이 인증서만으로 로그인하는 방법이다.
Docker Compose
본 장에서는 Docker Compose를 활용한 인프라 환경 구성에 대하여 알아본다. 웹 시스템에 서는 하나의 서버를 활용하여 서비스를 구현하지 않는 것처럼 도커 역시 여러개의 도커 컨 테이너를 활용하여 서비스를 제공하게 된다.
Compose를 정의하는 'docker-compose.yml' 파일에 이러한 환경 정보를 모아서 설정할 수 있다. 본 장에서는 다음의 내용을 학습하게 된다.
실제 웹이 서비스를 제공하는 환경은 3-tier 구조를 갖는다.
user ---> WEB --- WAS --- DB
WEB : 보이는 화면(1계층)
WAS : 데이터 처리(2계층)
DB : DB
WAS도 scale out을 통해서 수평적으로 계속 늘릴 수 있다.
DB도 클러스터를 구현해서 scale out해주면 user의 요청에 적절하게 대응할 수 있다. 이를 위해서는 container 구성시 WEB/WAS/DB 별도의 컨테이너를 만들자.
이걸 Docker Compose를 이용하면 보다 쉽게 구축할 수 있다.
1. docker-compose.yml 파일 만들기 -> 서비스 운영을 위한 환경설정 정보(볼륨/네트워크 정보)
2. docker-compose up
3. containers for service
* scale 조정 가능
docker-compose는 한대의 서버내에서 필요한 환경을 docker-compose.yml에 정의하고 이를 토대로 서비스를 배포하기 위한 인프라를 배포할 수 있다.
또한 해당 파일들을 기반으로 인프라 환경을 한꺼번에 삭제할 수도 있으며 필요한 서비스의 scale 조정도 가능하다.
단, 한대의 서버에서 스케일 조정이 된다는 점이 단점
예를들어 compose를 이용해서 web과 db를 연결해서 외부에 배포하는 서비스를 만들고 싶을때 WEB의 80번 포트를 공인 IP의 80번 포트와 연결한다.
외부 접속자들은 공인 IP로 접속하면 서버로 들어온다. 그리고 글을쓰면 글이 DB에 저장하는 환경을 만들 수 있다.
그런데 스케일이 조정이 되니 웹서버를 하나더 만드는 것이다. 이걸로 DB에 글을 등록하는데... 새로운 web은 다른 포트를 쓰게끔해야하지만... 사용자가 구지 다른 포트로 들어올리가 없다.
그래서 좋지가 않다...
이것보다는 서버를 3대 만들고 한대에서 서버를 배포하고 이와 유사한 서비스를 다른 서버에도 만든다.
이 서버들을 LB를 통해 나누어서 들어가면 분산처리가 가능해진다.
이 환경들을 cluster로 묶어야 하는데 이 기술을 swarm이라고 부름
도커 컴포즈는 디렉토리 내에서 모든 작업이 이루어 져야 한다. 디렉토리 위치가 달라지면 yml 파일을 못 읽는다.
- 실습
```
cd
cd docker
mkdir 0304 ; cd 0304
touch Dockerfile
touch docker-compose.yml
touch index.html
curl https://www.nginx.com > index.html
```
index.html의 title부분만 수정하자
```
docker build -t mynginx:1.0 .
```
```
vi docker-compose.yml
```
version: "3.3"
services:
websrv:
image: mynginx:1.0
networks:
- privatenet
volumes:
- privatevol:/usr/share/nginx/html
ports:
- "8001-8003:80"
restart: always
environment:
ENVTEST: test123
networks:
privatenet:
volumes:
privatevol: {}
```
docker-compose up -d --scale websrv=3
```
정상적으로 3개를 만들었다.
```
docker-compose ps
```
했는데 state가 Restarting에서 바뀌지를 않는다... 아마 Dockerfile에서 마지막 항목을 넣지 말았어야 했던거 같다. 다시 만들자.
Dockerfile을 수정해서 다시 해봐야겠다.
이번에는 잘된다.
접근이 되는 것도 확인된다.
docker-swarm
많은 트래픽을 처리할 수 있는 실용적인 시스템을 구축하려면 보다 많은 컨테이너가 각기 다른 호스트에 배치되어 이를 처리하도록 해야 할 것이다. 이를 위해서는 다수의 호스트와 컨테이너를 효율적으로 관리할 수 있는 방법을 고려해야 한다.
이를 위한 첫 번째 대안이 바로 도커 스웜 (Docker Swarm)이다. 도커 스웜은 여러 도커 호스트를 클러스터로 묶어주는 컨테이너 오케 스트레이션 도구의 한 종류이다. 오케스트레이션 도구를 활용하면 어느 호스트에 어느 컨테 이너를 배치할 것인지, 서로 다른 호스트에 위치한 컨테이너간 통신은 어떻게 조율해야 하 는지와 같은 수고를 덜 수 있으며, 호스트가 여러대로 나뉘어 있다고 하더라도 이를 신경쓰 지 않고 클러스터를 투명하게 다룰 수 있게 된다
1. centos 컨테이너 + db 컨테이너(mysql; mariadb -> ROOT_PASSW)
CENTOS 7 XE(Xpress Engine) 구축하기 (서비스 준비) (tistory.com)
CENTOS 7 XE(Xpress Engine) 구축하기 (서비스 준비)
안녕하세요 미씨오입니다. XE(Xpress Engine) 구축하는 방법에 대해서 공유하도록 하겠습니다. 회사에서 업무관련 게시판으로 사용하고 있는데요. 제가 사용하는 버전은 완전 예전에 받은 버전이여
missio1227.tistory.com
안된다.
XpressEngine Docker로 구성하기 (tistory.com)
XpressEngine Docker로 구성하기
나만의 홈페이지를 만들고 싶을 때, 처음부터 시작하는 방법도 존재하는 다양한 오픈소스 프로그램을 활용해서 방법도 있다. Wordpress라는 좋은 플랫폼도 존재하지만 이번 시간에서는 xpressengine
judo0179.tistory.com
이분의 도움을 받았다.
안타깝게도 잘되지는 않았다.
FROM centos:7
RUN yum clean all
RUN yum -y update
RUN yum -y install httpd
RUN yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum -y install epel-release yum-utils
RUN yum-config-manager --disable remi-php54
RUN yum-config-manager --enable remi-php74
RUN yum -y install php php-mysqlnd php-fpm php-cli php-gd php-mysql
RUN yum -y install php-mysql php-gd php-ldap php-odbc php-pear php-xml \
php-xmlrpc php-mbstring php-snmp php-soap curl curl-devel
ADD bbs.tar /var/www/html
RUN chmod 755 /var/www/html
RUN mkdir /var/www/html/bbs/files
WORKDIR /var/www/html/bbs
RUN chgrp apache files
RUN chmod 777 -R /var/www/html/bbs
EXPOSE 80
CMD httpd -D FOREGROUND
version: "3.3"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: test123
MYSQL_DATABASE: bbs
MYSQL_USER: bbs
MYSQL_PASSWORD: bbs
bbs:
image: bbs:1.0 # <--docker build -t bbs:1.0 .
volumes:
- bbs_data:/var/www/html/bbs
ports:
- "8001:80"
restart: always
depends_on:
- db
volumes:
db_data: {}
bbs_data: {}
docker swarm
현재 상태를 스냅샷으로 찍고 이전상태로 돌아와서 위의 환경에서 다시 시작하자
자원들을 하나의 풀에 넣어 관리및 사용/각각의 자원을 서버에 넣기 = 클러스터 만들기
이제 우리가 만든 vm을 100-103까지 만들것이다.
docker01 -> clone -> manager, worker 1-3
만들기
1) manager(관리자)
2) worker1 (관리자로부터 업무를 전달받고 이를 수행하는 역활)
이름부터 각 VM에 맞추어 바꾸어놓자
- IP 주소
manager : 211.183.3.100
worker1 : 211.183.3.101
worker2 : 211.183.3.102
worker3 : 211.183.3.103
host들을 적어놓자
- 모든 서버의 /etc/hosts 에 아래내용 추가
211.183.3.100
이제 클러스터를 구성해보자
manager에서 클러스터 구성을 위한 토큰을 worker들에게 제공해준다.
```
docker swarm init --advertise-addr 211.183.3.100
```
token이 나왔다. 이걸 복사해서 worker 들에게 뿌려주어야 한다.
진짜 별거 없다 그냥 복붙해주면 된다.
만약 까먹었다면
```
docker swarm join-token worker
```
을 해주면 토큰값이 나온다.
이러한 매니저는 두개가 있는게 좋다. 안정성때문에라도 이렇게 만들어야한다.
```
docker node ls
```
해주면 현재 매니저와 물린 호스트들을 확인할 수 있다.
매니저 설정이 안되어 있었다면 아예 확인이 불가능하다.
하지만 매니저는 언제든 다른 노드에 물릴수도 뺄수도 있다.
매니저에서 진급해 줄 수 있다.
반대로 강등시키어 줄 수 있다.
```
docker node promote worker1
docker node demote worker1
```
```
docker image pull nginx
docker service create --name myweb --replicas 4 -p 80:80 nginx # 서비스 복사해서 4개 만든다음 운영
docker service ps myweb
```
각각의 process가 어디에 예약중인지 확인할 수 있다.
그래서 실재 서버 ip로 가보면 웹페이지를 확인해볼 수 있다.
이렇게 manager에서 container 하나가 돌고 있는것을 확인할 수 있다. 이와 비슷하게 다른 서버에서도 docker container가 돌고 있다.
걔중 하나의 서버를 꺼버리자
```
docker container rm -f 컨테이너 ID
```
docker service ps myweb하면 위와같이 4개의 서비스가 아직도 있는것을 확인할 수 있다.
replica를 했기 때문에 무조건 고정된 숫자를 계속 유지하도록 동작하지 않는 곳에서 강제로 하나를 만들어 숫자를 맞춘다.
이 갯수를 조절하기 위해서
```
docker service scale myweb=2
```
myweb1, 2번만 돌고 있는것을 볼 수 있다.
그런데 서비스는 4개 서버에 다 접근된다.
```
docker network ls
```
하면 ingress가 보인다. 이건 overlay를 위한 네트워크이다.
ingress 네트워크는 network driver로 overlay를 사용하므로 전체 노드에 걸쳐서 통신이 가능하게 된다. 특정 컨테이너가 삭제되거나 동작하지 않더라도 해당 노드로의 접속이 들어오면 이를 오버레이를 통해 타 노드의 컨테이너(서비스)에서 이를 처리하게 됨.
```
docker service rm myweb
docker service ls # docker service ps myweb
```
없어졌다.
이걸 yaml을 이용해서 관리하면 더 편할텐데 이를 docker stack이라고 부른다.
그래서 docker swarm은 어떻게
도커에서 클러스터링을 통한 컨테이너 오케스트레이션은 도커스웜/쿠버네티스 가 있는데
도커만을 사용하여 오케스트레이션 할 수 있는 도구는 두가지
- docker swarm classic
- docker swarm mode(우리가 지금 쓰는거) -> 기본 도커 설치 패키지에 포함되어 있음, 그냥 도커 스웜이라고 부름
* 스웜과 k8s(Kubernetes)의 가장큰 차이점은 runtime으로 쓰는게 다르다.
-> 스웜은 docker only
-> k8s는 docker + podman + cri-o + rocket...(일반 밴더들 포함해서 확장성이 높음)
swarm classic은 위와같은 구조로 있을때 manager 옆에는 DB를 하나둔다. 그리고 각 worker에는 agent가 들어간다. 이 agent는 manager의 (관리) 매니저와 통신을 위해 manager과 연결된다. 그래서 각 agent가 매니저로부터 업무지시 받으면 agent는 runtime에게 전달한다. 그럼 docker는 받은 업무를 처리한다.
그럼 manager은 나와 연결된놈들의 상태를 알아야 무언가를 할 수 있다. 그럼 전체 클러스터의 정보를 담아놓을 곳이 필요하다. 그래서 DB의 분산코디네이터에서 확인해서 누가 살아있는지 체크한다. 문제는 너무 복잡하다. 그래서 분산코디네이터는 manager에 내장하고 agent도 빼서 manager가 docker와 직접 통신하게 한다.
기존 스웜 클래식이 분산코디네이터(클러스터 환경 정보 저장), 매니저(노드제어), 에이전트 (각 노드에 배치되어 런타임에게 업무 전달)가 나뉘어져 있었다면 스웜모드는 이를 모두 manager 내에 통합시켰다.
따라서, 매니저가 업무를 전달하면 이를 각 노드의 도커에게 직접 전달한다. 스웜은 docker engine에 기본적으로 포함되어 있다.
- manager(기본적으로 worker의 기능을 병행) - 나중에 관리만 하기를 원하게 됨
- worker
worker 안에는 role이 worker라고 적혀있다. 그런데 내가 각각에 label을 붙여서 seoul/busan 등등 붙여줄 수 있다. 그래서 role이 manager가 아니고 label의 zone이 seoul이면 손들라고 할 수 있다. 그럼 지정된 두곳에서만 컨테이너가 배포되도록 할 수 있다.
토큰을 이용하여 join 시킴
역으로 빠져나갈 수도 있음(manager도 빠져나갈 수는 있는데 --force로 할 수 있지만 쓰지마라)
```
docker swarm leave
```
Worker 쫓아내기
worker3에서
```
service docker stop
```
```
docker node rm worker3
```
하면 매니저에서 쫓아낼 수 있다.
서비스를 종료하지 않고 내가 나가면 쉽게 삭제할 수 있다.
```
docker swarm leave
```
```
docker node rm -f worker1
```
내가 강제로 없앨 수도 있다.
매니저도 그냥 나가자
```
docker swarm leave --force
```
이제 새로운 클러스터를 만들어보자 그리고 worker들을 모두 포함시켜주자
```
docker swarm init --advertise-addr 211.183.3.100
```
```
docker service create --name myweb --mode global nginx
```
하고 나니 거의 동시에 서비스들이 만들어졌다. 이렇게 하면 기존에 scale을 구지 세고 있던것을 안해도 된다.
대신에 replica가 아니라서 scale-up은 안된다.
worker1의 서비스를 강제 삭제해보자
서비스는 여전히 4개가 살아있다.
---
롤링업데이트
동작중인 컨테이너의 상태를 새로운 이미지로 업데이트 할 수 있다.
대충 만들자
하고나면 이미지 두개가 만들어진것을 확인할 수 있다.
이제 여기에다가 올려보자
먼저 도커 이미지의 이름을 바꾸어주어야한다.
모든 가상머신에서 docker에 로그인하자
이미지를 올려주자
그리고 manager 포함 네개의 서버에서 1.0, 2.0 모두 다운받자
```
docker service create -p 80:80 --name myweb2 --replicas 4 tonyhan18/myweb:1.0
```
보면 위와같이 nginx사이트가 보인다.
```
docker service update --image tonyhan18/myweb:2.0 myweb2
```
하면 업데이트 된다.
업데이트 완료되었다.
```
docker service rollback myweb2
```
하면 이전 모습으로 돌아올 수 있다.
---
이제 문제점이 만약에 서버에 이미지들이 없다면 온라인에서 이미지를 받아오려고 하기 때문에 스로틀링이 발생할 수 있다.
또 원격에서 다운받고 있는데 한개가 속도가 굉장히 빨라서 비대칭성 문제가 발생할 수 있다.
그래서 저장소를 매니저에 두면 이를 해결할 수 있다.