728x90
반응형

1. 로컬에서 만든 도커 이미지를 private registry인 하버 서버에 올리기

프라이빗 클라우드를 사용하기 때문에 Docker Hub와 같은 Public Image Registry를 사용할 수 없었다. Private Registry인 하버의 IP 주소와 도메인 주소만을 알고 있었다.

따라서 Dockerfile을 사용해서 빌드한 이미지를 압축파일 형식인 tar 파일로 저장하여 배포해야 했다.

  • 도커를 tar 파일로 저장하기 : save , export 명령어 사용
  • tar 파일을 도커 이미지로 저장 : load, import 명령어 사용
  • save, load 같이 사용 → 도커 이미지 저장하고 로드, 해당 이미지는 원본 이미지와 동일
  • export, import 같이 사용 → 도커 컨테이너 저장하고 로드, 원본 이미지를 아카이빙하여 하나의 레이어로 저장된 이미지로 추출

save, load 명령어를 이용하여 tar 파일로 만든 뒤 harbor에 접속해서 이미지로 만들었다.

[로컬에서 해야할 일]

  1. Docker를 사용해서 빌드 파일 이미지로 생성
    1. docker build {사용자 이름}/{이미지 이름}
    2. docker build --platform linux/amd64 -t kimtaeheon/discoveryservice:1.0 .
  2. docker save -o ${파일명.tar}
  3. scp ${파일명.tar} root@${Harbor Server}:/root

[Harbor 서버에서 해야할 일]

  1. docker load -i ${파일명.tar}
  2. docker tag ${이미지} ${Harbor Domain}/${이미지}
  3. docker push ${Harbor Domain}/${이미지}

여기까지 하면 Harbor 서버에 내가 만든 이미지가 올라간다.

[쿠버네티스에서 Deployment와 Service manifest 파일 작성]

  1. Deployment는 Pod 생성을 위해
  2. Service는 NodePort로 외부에 노출시켜서 실행 확인을 위해 30007번으로 포트를 열었다
apiVersion: apps/v1
kind: Deployment
metadata:
  name: discovery-deploy
  labels:
    app: discovery
spec:
  replicas: 1
  selector:
    matchLabels:
      app: discovery
  template:
    metadata:
      labels:
        app: discovery
    spec:
      containers:
      - name: discovery-service
        image: msa.harbor.com/discovery-service
        ports:
        - containerPort: 8761
---
apiVersion: v1
kind: Service
metadata:
  name: discovery-service
spec:
  type: NodePort
  selector:
    app: discovery
  ports:
    - port: 8761
        protocol: TCP
      targetPort: 8761
      nodePort: 30007

여기까지 하면 원래 정상적으로 30007번 포트로 Eureka Server가 보여야 한다. (그런데.. ㅜㅜ)

문제 1. ImagePullBackOff

pod 상태에서 해당 문제가 생겼다. 말 그대로 이미지를 제대로 가져올 수 없어서 생기는 문제였다.

Harbor에는 정상적으로 이미지가 있는데 이 문제가 생기는 이유는 harbor는 http이고 쿠버네티스는 https 서버이기때문에 이미지를 가져올 수가 없었다.

harbor를 https로 바꾸는 방법도 있지만, 쿠버네티스에서 컨테이너 런타임 엔진으로 사용하고 있는 containerd 설정과 harbor dns를 등록해두었다.

1. containerd 설정 변경

: containerd의 설정은 /etc/containerd/config.toml 에 있다. (Docker는 /etc/docker )

이전에 설정된 것을 변경해야 하는데, insecure_skip_verify = true 로 설정해두어야 한다.

2./etc/hosts 파일에 하버 도메인 등록

/etc/hosts 파일은 호스트 이름과 IP주소를 매핑하는 로컬 호스트 파일이다. DNS를 사용하지 않고도 호스트 이름을 IP 주소로 해석할 수 있어서 내부망이나 개발 환경에서 별도의 DNS 서버를 구성하지 않고도 호스트 이름을 사용하여 다른 서버와의 통신을 지원할 수 있다.

해당 파일에 다음 내용을 추가한다.

127.0.0.1 localhost
"하버 IP 주소" "하버 도메인 이름" 

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

이렇게 적용하면 ImagePullBackOff 오류는 사라진다.

문제 2. CrashLoopBackOff

이번에 Pod를 확인한 결과 다음과 같은 오류가 발생했다. 해당 오류의 원인을 찾기 위해 kubectl 을 이용해서 컨테이너에 접속해보았다.

[문제 찾는 과정..]

1. 컨테이너 접속

kubectl exec -it discovery-deployment-7f88c84866-rqm4r -- /bin/bash

→ 컨테이너를 찾을 수가 없었다. 로그를 확인해보았다.

2. 로그 확인

kubectl logs discovery-deployment-7f88c84866-rqm4r

→ exec /usr/local/openjdk-17/bin/java: exec format error

이건 Dockerfile의 첫 라인이였는데 여기서부터 오류가 난 것은 이미지 생성 오류라고 생각하여 검색해보았다.

예전에도 발생했었던,, Mac M1에서 이미지 빌드하면 linux에서 오류가 생기는 문제였다.

[해결] Docker: exec /usr/openjdk-11/bin/java: exec format error

 

[해결] Docker: exec /usr/openjdk-11/bin/java: exec format error

m1 docker build

velog.io

그래서 이미지를 빌드할 때, docker build --tag dockerfile:0.1 . 이렇게만 하면 안되고 platform을 환경 변수로 줘야 한다.

docker build --platform linux/amd64 -t kimtaeheon/discoveryservice:1.0 .


여기까지 하면 Pod가 잘 생성되고 NodePort를 통해 외부 포트 30007번에서 접근 가능하다.

 

728x90
반응형
728x90
반응형

www.acmicpc.net/problem/2606

문제

신종 바이러스인 웜 바이러스는 네트워크를 통해 전파된다. 한 컴퓨터가 웜 바이러스에 걸리면 그 컴퓨터와 네트워크 상에서 연결되어 있는 모든 컴퓨터는 웜 바이러스에 걸리게 된다.

예를 들어 7대의 컴퓨터가 <그림 1>과 같이 네트워크 상에서 연결되어 있다고 하자. 1번 컴퓨터가 웜 바이러스에 걸리면 웜 바이러스는 2번과 5번 컴퓨터를 거쳐 3번과 6번 컴퓨터까지 전파되어 2, 3, 5, 6 네 대의 컴퓨터는 웜 바이러스에 걸리게 된다. 하지만 4번과 7번 컴퓨터는 1번 컴퓨터와 네트워크상에서 연결되어 있지 않기 때문에 영향을 받지 않는다.

어느 날 1번 컴퓨터가 웜 바이러스에 걸렸다. 컴퓨터의 수와 네트워크 상에서 서로 연결되어 있는 정보가 주어질 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.

출력

1번 컴퓨터가 웜 바이러스에 걸렸을 때, 1번 컴퓨터를 통해 웜 바이러스에 걸리게 되는 컴퓨터의 수를 첫째 줄에 출력한다.

예제 입력 1

7
6
1 2
2 3
1 5
5 2
5 6
4 7

예제 출력 1

4


[문제 해설]

문제 이해는 아주 잘 되는 편이였다. 1번이 바이러스에 걸리면 1번과 연결된 모든 컴퓨터가 바이러스에 걸린다. 1번에 의해서 몇개의 컴퓨터가 바이러스에 걸리는지 확인하면 되는 문제이다.

 

먼저 1부터 해서 깊게 파고들어서 연결된 컴퓨터를 모두 확인해야 되기 때문에 DFS를 떠올릴 수 있다. DFS를 통해서 풀었다.

 

(밑에 코드는 정답은 아니고 시행착오 중 하나)

n = int(input())
m= int(input())
computer=[]
visited=[False]*(n+1)

for i in range(m):
    computer.append(list(map(int,input().split())))

def dfs(computer,v,visited):
    visited[v]=True
    for i in range(m):
        x=computer[i][0]
        y=computer[i][1]
        if not visited[y] and x==v:
            dfs(computer,y,visited)
            print(visited)
dfs(computer,1,visited)
answer=0
for i in range(1,n+1):
    if visited[i]:
        answer+=1
print(answer-1)

위에 코드는 처음에 짠 코드이다. 연결된 간선 모두를 반복문을 통해 확인하고 방문되지 않은곳을 다 방문하여 확인하였다. 예제 입력에 있는 숫자들을 복사하면 출력 값이 잘 나온다.

 

 그러나 제출하면 계속 '틀렸습니다' 가 되어서 코드를 계속해서 보았다.

 

 예제 입력을 조금만 틀어서 입력하니까 문제를 찾을 수 있었다.

7
6
1 2
2 3
5 1#여기만 바꿈
5 2
5 6
4 7

사실 연결된 것은 똑같기 때문에 같은 값이 나와야 되는데 출력값은 4가 아니였다. 

양쪽에 연결된 것을 확인하지 않았기 때문이었다.

 

양쪽에 연결하는 코드를 추가해주면 된다.

n = int(input())
m= int(input())
computer=[]
visited=[False]*(n+1)

for i in range(m):
    computer.append(list(map(int,input().split())))

def dfs(computer,v,visited):
    visited[v]=True
    for i in range(m):
        x=computer[i][0]
        y=computer[i][1]
        if not visited[y] and x==v:
            dfs(computer,y,visited)
        if not visited[x] and y==v:
            dfs(computer,x,visited)
dfs(computer,1,visited)
answer=0
for i in range(1,n+1):
    if visited[i]:
        answer+=1
print(answer-1)

 

728x90
반응형

+ Recent posts