본문 바로가기

Docker & Kubernetes

쿠버네티스(Kubernetes) - k8s에서 Docker 컨테이너 사용하기

쿠버네티스에서 도커 이미지를 이용한 파드 생성

https://gitlab.com/nodo3482/ys-k8s/-/tree/main/config

VagrantFile을 통해 노드를 생성하면서 우리는 install_pkg.sh에 이미 git, docker 패키지를 설치하였다. 따라서 노드에 접속하여 docker관련 명령어를 사용하는 것이 가능하다.

 

- 마스터노드 접속해서 docker ps 명령어를 실행한 모습.

 

Dockerfile로 Build하여 deployment 파드 생성하기

= Dockerfile

FROM openjdk:8
LABEL description="Java Application builder"
EXPOSE 60433
RUN git clone https://github.com/iac-source/inbuilder.git
WORKDIR inbuilder
RUN chmod 700 mvnw
RUN ./mvnw clean package
RUN mv target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]

 

# Dockerfile 실행하여 docker image 생성
# (뒤에 .은 현재디렉터리에 Dockerfile이 있으므로)
[root@m-k8s-ys vagrant]# docker build -t java-apps .
.....
Step 8/10 : RUN mv target/app-in-host.jar /opt/app-in-image.jar
 ---> Running in e9a42289821f

 ---> f74a1e67b379
Removing intermediate container e9a42289821f
Step 9/10 : WORKDIR /opt
 ---> 44f9547377a1
Removing intermediate container 2c2fce9a90a8
Step 10/10 : ENTRYPOINT java -jar app-in-image.jar
 ---> Running in d7f45de8f923
 ---> 12f5c5642a9a
Removing intermediate container d7f45de8f923
Successfully built 12f5c5642a9a

# java-apps 이름으로 생성된 이미지 획인
[root@m-k8s-ys vagrant]# docker images java-apps
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
java-apps           latest              12f5c5642a9a        48 seconds ago      633 MB

(!) 위에서 설명하는 방식은 컨테이너 내부에서 컨테이너 빌드를 하는 방법인데, 이방법은 이미지 용량이 커지는 문제가 있어서 좋지 않은 방법이다. 따라서 해결할 수 있는 방법은 최적화를 하여 컨테이너를 빌드하는 방법이다.

 

최적화해 컨테이너 빌드하는 방법은?

멀티 스테이지 빌드(Multi-Stage Build)를 사용하는 것이다. 최종 이미지의 용량을 줄일 수 있고 호스트에 어떠한 빌드 도구도 설치할 필요가 없다. 단, docker버전이 docker-ce 17.06 이상부터 지원하므로, 예제에서 진행했던 1.13.1에서는 동작하지 않으므로 유의.

(실제 뭔가를 지원하지 않는다는 오류가 발생하더라..)

 

= vagrant에서 node의 docker version을 18.9.9로 변경하여 적용하였다. 아래 깃저장소 참고.

https://gitlab.com/nodo3482/ys-k8s/-/commit/48ccdd6c0158e277698f817469116dbbbc1eeaab

 

= 18.9.9 버전에서 Dockerfile

FROM openjdk:8 AS int-build
LABEL description="Java Application builder"
RUN git clone https://github.com/iac-source/inbuilder.git
WORKDIR inbuilder
RUN chmod 700 mvnw
RUN ./mvnw clean package

FROM gcr.io/distroless/java:8
LABEL description="Echo IP Java Application"
EXPOSE 60434
COPY --from=int-build inbuilder/target/app-in-host.jar /opt/app-in-image.jar
WORKDIR /opt
ENTRYPOINT [ "java", "-jar", "app-in-image.jar" ]
# Dockerfile로 multistage-img 라는 이름으로 이미지 생성
[root@m-k8s-ys docker-test]# docker build -t multistage-img .

사설 레지스트리 구성하기

도커 이미지를 레지스트리에 저장해서 사용할 수도 있지만, 기술 보안등의 이슈를 이유로 전용 사설 저장소를 만들어서 운영할 수도 있다.

 

= create-registry.sh

: 인증서를 만들어 배포한 뒤 레지스트리를 구동해주는 쉘스크립트

#!/usr/bin/env bash
certs=/etc/docker/certs.d/192.168.56.10:8443
mkdir /registry-image
mkdir /etc/docker/certs
mkdir -p $certs
# HTTPS 접속시 서버의 정보가 담긴 인증서와 주고 받는 데이터를 암복호화할 때 사용하는 키가 필요한데, 인증서를 생성하는 요청서가 담긴
# tls.csr 파일로 HTTPS 인증서인 tls.crt 파일과 암호화와 복호화에 사용하는 키인 tls.key 파일을 생성
openssl req -x509 -config $(dirname "$0")/tls.csr -nodes -newkey rsa:4096 \
-keyout tls.key -out tls.crt -days 365 -extensions v3_req

# ssh 접속을 위한 비밀번호를 자동으로 입력하는 sshpass 설치
yum install sshpass -y
for i in {1..4}
  do
    sshpass -p vagrant ssh -o StrictHostKeyChecking=no root@192.168.56.10$i mkdir -p $certs
    sshpass -p vagrant scp tls.crt 192.168.56.10$i:$certs
  done

cp tls.crt $certs
mv tls.* /etc/docker/certs

docker run -d \
  --restart=always \
  --name registry \
  -v /etc/docker/certs:/docker-in-certs:ro \
  -v /registry-image:/var/lib/registry \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/docker-in-certs/tls.crt \
  -e REGISTRY_HTTP_TLS_KEY=/docker-in-certs/tls.key \
  -p 8443:443 \
  registry:2

= remover.sh

: 설정을 지워주는 쉘스크립트

#!/usr/bin/env bash
certs=/etc/docker/certs.d/192.168.56.10:8443
rm -rf /registry-image
rm -rf /etc/docker/certs
rm -rf $certs

yum -y install sshpass
for i in {1..4}
  do
    sshpass -p vagrant ssh -o StrictHostKeyChecking=no root@192.168.56.10$i rm -rf $certs
  done

yum remove sshpass -y
docker rm -f registry
docker rmi registry:2

= tls.csr

: 인증서를 만들 때 사용한다.

[req]
distinguished_name = private_registry_cert_req
x509_extensions = v3_req
prompt = no

[private_registry_cert_req]
C = KR
ST = SEOUL
L = SEOUL
O = gilbut
OU = Book_k8sInfra
CN = 192.168.56.10

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.0 = m-k8s
IP.0 = 192.168.56.10

= success.yaml

: 사설 레지스트리 저장소를 사용한 deployment 파드생성 파일

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: success
  name: success
spec:
  replicas: 3
  selector:
    matchLabels:
      app: success
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: success
    spec:
      containers:
      - image: 192.168.56.10:8443/multistage-img
        name: multistage
        resources: {}
status: {}

 

# 레지스트리 저장소 생성
[root@m-k8s-ys vagrant]# ./create-registry.sh

# 레지스트리 저장소 컨테이너 확인
[root@m-k8s-ys vagrant]# docker ps -f name=registry
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                             NAMES
96365f09c7e6        registry:2          "/entrypoint.sh /etc…"   10 seconds ago      Up 9 seconds        5000/tcp, 0.0.0.0:8443->443/tcp   registry

# 레지스트리 저장소에 이미지(+태그) 생성
# 위에서 생성했던 multistage-img 이미지로 진행한다
[root@m-k8s-ys vagrant]# docker tag multistage-img 192.168.56.10:8443/multistage-img

# 레지스트리 저장소에 이미지 등록
[root@m-k8s-ys vagrant]# docker push 192.168.56.10:8443/multistage-img
The push refers to repository [192.168.56.10:8443/multistage-img]
3106419682c4: Pushed 
1d834f05c29e: Pushed 
b29380a5a354: Pushed 
231bdbae9aea: Pushed 
ba16d454860a: Pushed 
1a5ede0c966b: Pushed 
latest: digest: sha256:f672005b5fb2200db16a494ef66367a7252260b5d54af7dc613f3675df713068 size: 1583

# success.yaml 파일로 deployment 파드 생성
[root@m-k8s-ys vagrant]# kubectl apply -f success.yaml 
deployment.apps/success created

# 생성 파드 확인
[root@m-k8s-ys vagrant]# kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
success-684ff5fcb9-b4ljm   1/1     Running   0          46s   172.16.80.136    w2-k8s-ys   <none>           <none>
success-684ff5fcb9-ql746   1/1     Running   0          46s   172.16.193.198   w1-k8s-ys   <none>           <none>
success-684ff5fcb9-x9wnb   1/1     Running   0          46s   172.16.138.70    w3-k8s-ys   <none>           <none>

# 파드가 요청하는지 확인
[root@m-k8s-ys vagrant]# curl 172.16.80.136
src: 172.16.96.128 / dest: 172.16.80.136

참고자료

= 서적 - 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커, 길벗 - 제 4장