쿠버네티스 docker 지원 중단에 따른 대안 🐳 🥊 🐙

bo-yoon·2021년 10월 9일
4

kubernetes

목록 보기
8/10

쿠버네티스가 v1.20 이후 컨테이너 런타임으로서 도커를 사용을 depricated🥊 한다고 한다

그렇기 때문에 컨테이너 런타임을 docker 에서 쿠버네티스가 계속 지원하는 다른 종류로 변경할 필요가 있다.

참고 : https://kubernetes.io/ko/blog/2020/12/02/dont-panic-kubernetes-and-docker/

그림 출처 : https://www.redhat.com/ko/topics/containers/kubernetes-architecture

기존 도커 같은 경우 다음과 같이 도커심이라는 구성요소를 사용해 kubernetes와 연결을 지원하였다. 이유는 도커가 컨테이너 런타임 인터페이스인 CRI를 준수하지 않았기 때문이다. 쿠버네티스 v1.23부터는 이 도커심의 지원이 제거된다. 그렇다면 v1.20 부터 Docker로 빌드한 이미지를 사용 불가능할까?

그것은 아니다. docker build 한 이미지는 kubernetes 클러스터에서 계속 실행할 수 있다. 쿠버네티스가 지원하는 다른 컨테이너 런타임인 containerd 와 CRI-O 가 도커 이미지를 가져와 실행하는 법을 알고 있기 때문이다.

그럼 쿠버네티스가 지원하는 다른 컨테이너 런타임 종류를 알아보자.





쿠버네티스 지원 컨테이너 런타임 종류

지금 부터 소개하는 컨테이너 런타임은 쿠버네티스에서 만든 컨테이너 런타임 인터페이스와 호환되는 컨테이너 런타임이다. 따라서 도커심같은 중간 매체가 필요없다.


1) containerd

https://kubernetes.io/ko/docs/setup/production-environment/container-runtimes/#containerd

  • 도커 프로젝트에서 분리된 형태로 도커 자체적으로도 containerd를 사용한다. 따라서 Docker를 설치하면 containerd 도 설치된다.

2) CRI_O

https://github.com/cri-o/cri-o

장점

  • 컨테이너 실행을 경량화

단점 :

  • 도커가 제공하는 컨테이너 생성 및 이미지 빌드 기능은 제공안함
    • 그래서 도커대신에 이미지를 빌드할 수 있는 툴(kaniko, buildash, Podman, Skpeo) 을 사용해야함



환경
kubernetes 1.22

쿠버네티스 컨테이너 툴

또한 이런 컨테이너 런타임 컨테이너는 이미지를 빌드할 수 있는 기능을 제공하는 툴이랑 같이 사용할 수 있는데 종류는 아래와 같이 있다.


1) Kaniko

https://github.com/GoogleContainerTools/kaniko

  • Dockerfile에서 컨테이너 이미지를 빌드하는데 사용하는 기능
  • 도커 데몬이 필요하지 않아 kubernetes 클러스터와 같이 루트 권한이 없는 모든 환경에서 실행가능
  • 도커를 사용해서 이미지 생성, kaniko를 사용하여 이미지 실행

2) Buildah

https://buildah.io/

  • 도커 파일 없이 다른 스크립트 언어를 사용하는 것이 목표. 도커 파일도 사용가능

  • OCI 이미지 생성

3) Podman

  • buildash 가 생성한 이미지로 컨테이너 유지, 관리

4) Skopeo

  • 이미지 저장소에 대한 접근 제어 제공

buildah, Podman, skopeo는 도커기능을 역할별로 나눠서 제공해준다.

kaniko는 buildah의 역할이랑 같다. 다만 kaniko는 하나로 충분하지만 buildah는 podman이랑 같이 사용해야 한다.





1) containerd 를 컨테이너 런타임으로 사용한 쿠버네티스 설치

  • 기존에 있던 쿠버네티스, 도커 삭제
kubeadm reset
sudo apt-get purge kubeadm kubectl kubelet kubernetes-cni kube*   
sudo apt-get autoremove  
sudo rm -rf ~/.kube

sudo apt-get purge docker-ce=18.06.2~ce~3-0~ubuntu -y
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get autoremove 

  • 잘 삭제 됬는지 확인
  docker version
  kubectl version
  kubeadm version
  kubelet --version

  • 필수 구성요소 설치
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 필요한 sysctl 파라미터를 설정하면 재부팅 후에도 유지된다.
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# 재부팅하지 않고 sysctl 파라미터 적용
sudo sysctl --system

  • containerd 설치

https://docs.docker.com/engine/install/ubuntu/

sudo apt-get update 

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
    
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

 echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
  
sudo apt-get update
sudo apt-get install containerd.io

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd


  • systemd cgroup 드라이버 사용
vi /etc/containerd/config.toml
 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true
sudo systemctl restart containerd


  • 쿠버네티스 설치

https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#%EC%BB%A8%ED%8A%B8%EB%A1%A4-%ED%94%8C%EB%A0%88%EC%9D%B8-%EB%85%B8%EB%93%9C%EC%97%90%EC%84%9C-kubelet%EC%9D%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-cgroup-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84-%EA%B5%AC%EC%84%B1

sudo apt-get update
sudo apt-get upgrade

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

sudo apt-get update
sudo apt-get upgrade

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl


kubeadm version
kubelet --version
kubectl version # 클라이언트만 정상인지 확인

  


  • 마스터 노드 세팅
# 소캣 지정 필수
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.60.4 --cri-socket /run/containerd/containerd.sock



  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 워커 노드 세팅
kubeadm join 192.168.60.4:6443 --token scfdsafw.g1fsa.dfmhnm6 \
	--discovery-token-ca-cert-hash sha256:85efdaskfja;sdlkf58efb5 --cri-socket /run/containerd/containerd.sock

vi kube-flannel.yml

kubectl apply -f kube-flannel.yml

이렇게 작업을 완료하고

다음과 같이 kubectl get node -o wide를 쳤을때 컨테이너 런타임이 containerd 가 뜨면 된다.

root@master:~# kubectl get node -o wide
NAME     STATUS   ROLES                  AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
master   Ready    control-plane,master   29h   v1.22.3   192.168.60.4   <none>        Ubuntu 18.04.6 LTS   5.4.0-89-generic   containerd://1.4.11
node01   Ready    <none>                 29h   v1.22.3   192.168.60.5   <none>        Ubuntu 18.04.6 LTS   5.4.0-89-generic   containerd://1.4.11


2) Buildah, Podman 사용

  • Buildah 설치
sudo apt-get update
sudo apt-get -y install buildah

간단한 스프링 부트 어플리케이션 올려보기
예전에 간단하게 만든 어플리케이션을 수정하여 생성
https://github.com/bo-yoon/efk_sample.git

Dockerfile

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
  • Buildah 사용해서 이미지 생성
buildah bud -t yoonkwon23/bps-app:latest .

buildah bud -t yoonkwon23/bps-app:latest .
STEP 1: FROM openjdk:8-jdk-alpine
STEP 2: ARG JAR_FILE=*.jar
STEP 3: COPY ${JAR_FILE} app.jar
STEP 4: ENTRYPOINT ["java", "-jar", "/app.jar"]
STEP 5: COMMIT yoonkwon23/bps-app:latest
Getting image source signatures
Copying blob f1b5933fe4b5 skipped: already exists
Copying blob 9b9b7f3d56a0 skipped: already exists
Copying blob ceaf9e1ebef5 skipped: already exists
Copying blob a760e1904a6e done
Copying config e587cd1ca6 done
Writing manifest to image destination
Storing signatures
e587cd1ca6c4e97b25cce50709dc8c44d855201f4e783461327829a4850d6f22


* Podman 설치

:https://help.clouding.io/hc/en-us/articles/360011382320-How-to-Install-and-Use-Podman-on-Ubuntu-18-04

add-apt-repository -y ppa:projectatomic/ppa

sudo apt-get -y install podman

podman info

파드맨 인포를 보면 oci로 containerd가 설정되어 있는 것을 확인할 수 잇다.

  • podman으로 애플리케이션 실행
 echo -e "[registries.search]\nregistries = ['docker.io']" | sudo tee /etc/containers/registries.conf
 
 podman run hello-world
 
 podman images
REPOSITORY                      TAG      IMAGE ID       CREATED      SIZE
docker.io/library/hello-world   latest   feb5d9fea6a5   6 days ago   17.4 kB

 podman ps -a
CONTAINER ID  IMAGE                                 COMMAND  CREATED             STATUS                         PORTS  NAMES
208883ad3ee2  docker.io/library/hello-world:latest  /hello   About a minute ago  Exited (0) About a minute ago         awesome_tharp

 podman login  docker.io
  

skopeo 설치

  
    sudo apt-get -y install skopeo


ecr을 사용해서 쿠버네티스 파드 실행시켜보기

aws 세팅 및 이미지 생성

빌드한 이미지를 사용

root@master:~# buildah images
REPOSITORY                     TAG      IMAGE ID       CREATED          SIZE
localhost/yoonkwon23/bps-app   latest   2457476c89a6   10 minutes ago   133 MB

aws cli 세팅 (파이썬은 이미세팅되어 있음)

root@master:~# python3 --version
Python 3.6.9


# cli 설치
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip


sudo ./aws/install

aws --version

aws 계정 로그인

aws configure

AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: ap-northeast-2
Default output format [None]: json 

buildah, podman ecr로그인

aws ecr get-login-password --region ap-northeast-2 | podman login --username AWS --password-stdin {ecr 주소}
Login Succeeded!


aws ecr get-login-password --region ap-northeast-2 | buildah login --username AWS --password-stdin {ecr 주소}
  
Login Succeeded!

buildah push

buildah {이미지 id} tag {이미지번호} {ecr 주소}:latest


buildah push {ecr 주소}:latest

ecr 을 보니 정상적으로 push한 것을 확인할 수 있다.



쿠버네티스로 파드 올려보기

이제 쿠버네티스를 사용할 준비가 다 되었다.

파드를 올려보자!


  podman tag {ecr 주소}:latest {ecr 주소}:3
  podman push {ecr 주소}:3

아까 buildah 를 통해 만든 이미지가 있었는데 그 이미지를 podman으로 변환 후, ecr로 push 한다.

그리고 이 이미지를 베이스로 컨테이너를 실행한다.

podman run -id --name sample-pod2 -p 8090:8090 {ecr 주소}:3

이렇게 작업하면 podman ps 하면 컨테이너가 떠있는 것을 확인할 수 있는데

  
 podman generate kube {컨테이너 id}

라고 치면 pod 타입의 yaml 파일 형식이 생겨날 것이다.

root@master:~# cat podman2.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
  app: sample-pod2
name: sample-pod2
spec:
containers:
- env:
  - name: PATH
    value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
  - name: TERM
    value: xterm
  - name: HOSTNAME
  - name: container
    value: podman
  - name: LANG
    value: C.UTF-8
  - name: JAVA_HOME
    value: /usr/lib/jvm/java-1.8-openjdk
  - name: JAVA_VERSION
    value: 8u212
  - name: JAVA_ALPINE_VERSION
    value: 8.212.04-r0
  image: {ecr 주소}:{버전정보}
  name: sample-pod2
  ports:
  - containerPort: 8090
    hostPort: 8090
    protocol: TCP
  resources: {}
  securityContext:
    allowPrivilegeEscalation: true
    capabilities: {}
    privileged: false
    readOnlyRootFilesystem: false
  stdin: true
  workingDir: /
status: {}

이것을 복사해서 podman2.yaml 이라는 파일을 만들어주었다. (첫번째는 실패했다...)

그리고 buildah images, podman images로 관련된 이미지를 다 삭제해준다. 이미지가 정상적으로 pull 되는지 확인하기 위해서이다.

이제 kubectl apply -f podman2.yaml 를 해본다

root@master:~/efk_sample# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
sample-pod2   1/1     Running   0          27m

정상적으로 뜨는 것을 확인할 수 있다.



결론

  • 아직까지 전부 사용해본 것은 아니지만 쿠버네티스 1.22 이상으로 갈 경우 기존에 이미 서버가 구성되어있고 도커를 계속 사용하고 싶을 때는 containerdKaniko 조합을, 아예 도커를 사용하지 않고 싶을 경우 CRI_Obuildah, Podman, skopeo 조합을 사용하는 것이 좋을 것 같다.

tobe

  • 이번에는 파드만 올려보았지만 다음에는 서비스와 인그레스를 붙여 전체적인 구성을 진행해보자
profile
개발 로그 🍎 🍎 🍎

0개의 댓글