🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

블로그

일프로

[kubernetes] 쿠버네티스 첫 오브젝트 잘 끼우기 #6

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 오늘 공부할 내용이 쿠버네티스에서 사용되는 오브젝트들의 한 20% 정도가 되지 않을까 싶어요. 그동안 공부한 양이 적지도 않았고언제 쿠버네티스를 다 배우나 무거운 마음일 수도 있는데 제가 좀 안심이 되는 얘기를 드리면..혹시 파레토의 법칙 이라고 들어보셨나요? 예를들어, 우리나라의 20% 인구가 80%의 땅을 갖고 있다던가, 회사에 100명이 일하고 있는데 20명이 사실 그 회사에 80% 일을 하고 있다는 거죠. 수학적으로도 증명 가능한 말이라고 하고요.결국 원인의 20%가 80%의 결과를 만들어낸다는 뜻인데 저는 이번 강의를 이렇게 말씀드릴 수 있을 것 같아요. 오늘 배울 20%의 오브젝트들이 앞으로 쿠버네티스에서 자주 쓰는 오브젝트의 80% 입니다. 그렇기 때문에 오늘 강의가 정말 중요하고 이번 블로그도 끝까지 잘 읽어 주시길 부탁 드릴게요.   이번 강의는 제가 오랜 시간 걸려서 쿠버네티스를 이해했던 단계들을 바탕으로 구성을 한 거고요. 오브젝트를 잘 이해하는 방법으로 세 가지 단계를 준비를 했습니다.쿠버네티스의 어떤 기능은 그림을 그려볼 때 이해가 쉽고, 어떤 기능은 실제 App이랑 동작을 하는 걸 봐야지 이해가 정확해요. 그리고 어떤 기능은 쿠버네티스 내부 동작을 아는 게 중요한데, 이번 수업에서는 [Object 그려보며 이해하기]만 다룰 거고요. Object 그려보며 이해하기카페 실습 자료실 링크 (link) 이 단계에서는 위 강의 자료실에 실습으로 사용될 yaml 파일을 읽어보면서 오브젝트들을 하나씩 그려보고, 각 오브젝트들에 대한 역할이나 기능들을 살펴보겠습니다.이제 Object들을 하나씩 그려 보면서 역할이나 기능들을 간략하게 설명을 드릴게요.Namespace를 보면 Namespace는 Object들을 그룹핑 해주는 역할이에요. 그리고 metadata에 name이랑 label이 있는데 일단 그림만 그려놓고 넘어갈게요.그리고 다음으로 Deployment는 Pod를 만들고 업그레이드를 해주는 역할이구요. 여기에 namespace로 위에서 만들었던 이름이 있죠? 이렇게 하면 이 Deployment는 이 Namespace에 소속이 됩니다. 그리고 여기 이름이 있는데 한 namespace 안에서 이 이름은 중복이 되면 안되요. 그리고 label이랑 이 selector는 앞으로 계속 나올텐데 한번에 정리를 해서 설명을 드릴 거라 일단 이런 게 있다고만 알고 넘어가고요.그리고 replicas는 pod를 2개를 만들라는거고 strategy의 RollingUpdate는 deployment 기능의 핵심인데, 이 업데이트 방식에 대해서는 다음 강의에서 실습으로 해볼거에요. 그리고 template 부터가 이 내용대로 pod가 만들어진다고 보면 되는데, nodeSelector는 pod를 띄울 노드를 선택하는 거고 containers라는 속성이 있고 그 밑에 옵션들이 쭉 있는데 이 image는 제가 DockerHub에 이 이름으로 컨테이너 이미지를 올려놨기 때문에 여러분들이 이 image에 이렇게 넣으면 다운을 받아서 쓸 수 있는 거예요.  그리고 밑에 envFrom가 있고 configmap과 연결이 되어 있는데, Application에 환경 변수랑 관련된 부분이고 configmap은 그 값을 제공해 주는 역할을 해요.그 밑에 프로브들이 3개가 있는데 startupProbe는 App이 잘 기동이 됐는지 체크를 하고 있다가 기동이 안 되면 App을 재기동시키고요. 잘 됐으면 이 밑에 readinessProbe랑 livenessProbe를 시작 시켜요. 그래서 readinessProbe는 App에 트래픽을 연결 할 건지를 결정하는 속성이고 이 livenessProbe는 App이 정상이 아니면 재시작을 시킬 건지 판단하는 속성이에요. 정말 중요한 속성이고 이건 실제 App기능을 보면서 자세히 이해를 해 볼 거고요.다음으로 resources는 pod에 CPU랑 memory를 할당을 시킬 거고 최대 limit까지 쓸 수 있다는 설정이 있는데 이걸 설정하지 않으면 pod가 노드의 자원들을 모두 써버리게 됩니다.그리고 volumeMounts가 있는데 이 mountPath는 pod 내부에 만들어지는 디렉토리이구요. 이 이름이랑 volumes에 이 이름이 매칭이 되서 실제 persistentVolumeClaim이라는 object랑 연결이 되는 거에요. 그리고 secret-datasource도 이렇게 name으로 연결이 되면서 secret object랑 연결이 됩니다.  다음으로 Service고요. 이렇게 metadata 3세트는 자주 나올 거예요. namespace에 속한 object고 name이랑 labels이 있죠. 그리고 밑에 selector랑 ports, type이 있는데, 이 Service의 역할은 pod한테 트래픽을 연결시켜 주는거에요. 근데 이름을 보면 한 namespace안에는 이름이 중복되면 안 된다고 했잖아요? 정확히는 같은 종류의 object끼리 이름이 같으면 안 되는 거예요. 그래서 Service랑 Deployment는 서로 다른 object라 이름이 같아도 되고요.이제 ConfigMap을 보면 pod의 환경변수 값을 제공하는 역할이고요. 이렇게 metadata 3세트랑 그리고 data가 있는데 이게 아까 말했던 환경변수로 들어갈 값의 내용이에요. 그리고 밑에 Secret도 ConfigMap이랑 비슷한데 pod에 좀 더 중요한 값을 제공하는 역할로 쓰여요. 다음 강의에서 App기능을 실습을 해보면서 좀 더 이해를 해 볼게요. 여기서는 data가 아니고 stringData가 있는데 좀 다르죠? 이렇게 쓰면 stringData 내용들이 pod 안에 파일로 만들어집니다.  그리고 PersistentVolumeClaim이 있고 pod에서 pv를 지정할 때 사용을 하는데, 밑에 저장 공간을 얼마나 사용할지 그리고 이 저장 공간의 accessModes로 읽기/쓰기가 가능하다는 옵션이 있는데, 이 내용은 이번 실습에서는 동작하지 않고요. 그냥 필수값이라서 넣어둔 거라 다음번에 Volume만 다루는 강의에서 다시 설명을 드릴게요. 이번 실습에서는 selector만 쓰입니다.그리고 다음으로 PersistentVolume인데, 실제 Volume을 지정하는 역할을 하고요. 근데 여기에는 namespace가 없죠? 이 object들의 가장 큰 범위가 Cluster거든요. Namespace도 Cluster 안에 속해 있는 object고요. PV도 여기에 만들어지는데,object들은 크게 두 분류로 나뉘어요. Namespace랑 PersistentVolume은 Cluster Level의 Object라고 하고요. Deployment랑 Service들은 Namespace Level에 Object라고 해요. 그리고 각 object들은 자신의 level이 있기 때문에 Deployment는 PV처럼 Cluster level에 만들어 질 수가 없습니다.다시 PV로 돌아와서 마찬가지로 이런 내용들은 일단 넘어가고, local이 중요한데 path를 volume으로 사용하겠다는 내용이에요. 그리고 그 대상 노드는 밑에 nodeAffinity가 있는데, 좀 복잡해 보이지만, nodeSelector랑 똑같이 결국 Master Node를 지정한다는 내용입니다. 그래서 여기에 path가 사전에 없으면 PV를 만들 때 문제가 생기기 때문에 디렉토리를 미리 만들어 준 거고요.  그리고 이제 마지막으로 HPA인데, 부하에 따라 pod를 늘려주고 줄여주는 스케일링 역할을 하구요. scaleTargetRef로 그 스켈링 대상을 지정을 하고, min/maxReplicas는 최소 두 개의 pod를 유지를 하고 있다가 부하가 생기면 최대 4개까지 늘어나도록 설정을 한 거예요. 그리고 metrics라는 설정은 pod의 cpu가 평균 40%가 늘어나면 스케일 아웃을 하라고 설정을 한 겁니다. 그리고 밑에 behavior는 pod가 한번 증가를 한 후에 600초, 그러니까 10분 동안 또 pod가 추가적으로 늘어나지 않게 하는 설정인데, pod가 2개에서 3개로 늘어나자마자 부하가 더 증가한다고 해서 바로 4개로 늘리고 싶진 않을 때 이런 설정을 해요.그리고 마지막으로 namespace에 대한 기능을 하나 더 말씀드리면, namespace를 삭제하면 이 안으로 만든 모든 object가 같이 삭제가 되거든요. 그래서 실습을 하고 강의에서 배포한 object를 모두 삭제를 할 때는 이 namespace를 삭제하는 명령 하나만 날리면 되구요. PV는 namespace에 속하지 않기 때문에 별도로 한번 더 삭제를 해 줘야 되요.그럼 여기까지 오브젝트들을 봤는데 지금 좀 혼란스럽고 이해가 안되는 상황이라면 그게 맞아요. 현재까지는 각 object들이 어떤 역할을 하는지 대략적인 느낌만 이해를 하면 됩니다 :)  Object 그려보며 이해하기 - (label/selector/naming) (1)제가 대리 때, 팀에 차장님 한 분이 새로 들어오셨는데, 같이 일 한지 한 두 달이 넘었을 때였어요. 옆팀 부장님이 저한테 새로 온 차장님 이름을 물어보시더라고요. 근데 저는 평소 강차장님이라고만 불러서 이름은 처음 인사를 할 때 듣고 까먹은 상태였거든요. 나중에 확인해 봐야지 하면서 차일피일 미루고 있었는데, 다행히도 이 부장님께서는 제 대답에 딜레이를 느끼시고 바로 다른 분한테 물어봤습니다. 근데 저는 이 상황이 많이 부끄러웠어요.여러분도 이렇게 시간이 어느 정도 지났을 때 모르고 있으면 부끄러워지는 상황들이 있지 않나요?지금부터 배울 이 내용이 바로 그런 느낌이에요. 저도 실제로 쿠버네티스를 시작하고 2년 정도가 지나서야 이 부분을 신경쓰기 시작했는데, 해당 내용은 강의 영상에서 잘 설명을 드릴 예정이고 여러분들은 부디 저와 같은 실수를 하지마시고 잘 챙기시길 당부 드릴께요. Object 그려보며 이해하기 - (label/selector/naming) (2)여기까지 읽으시느라 정말 수고하셨고요. 처음 이런 내용을 들으시는 분께는 뭔가 많은 내용처럼 보일 수도 있지만 정말 자주 쓰는 기능들이고, 조금만 쓰다 보면 금방 익숙해지는 부분들이니까 너무 부담 갖지 마세요.그럼 오늘 블로그는 여기까지 마치겠습니다. ps. 뒤로가기 함부로 누르지마라. 너는 누구에게 한 번이라도 좋아요♡를 준 사람이었느냐 :)

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeops첫오브젝트잘끼우기

일프로

[쿠버네티스] 컨테이너 한방 정리 #3

 기술의 흐름으로 이해하는 컨테이너- 이미지 참고 : 쿠버네티스 어나더 클래스 (https://inf.run/Acobj) 쿠버네티스는 이제 [컨테이너]랑 [가상화] 그리고 [데브옵스]속에 깊숙히 자리잡고 있습니다. 그래서 이 세 가지를 알아야 쿠버네티스를 더 잘 알 수 있게 되는데, 이 단어들은 정말 큰 개념이라서 그냥 용어 설명으로는 이해하기 힘들어요. 그래서 기술에 전반적인 배경을 이해하는 게 중요하다고 생각합니다.그래서 이번 강의는 [컨테이너 한방 정리]로, 쿠버네티스를 잘 이해하기 위해컨테이너를 중심으로한 여러 배경 흐름 들을 이야기 해요. 1. Linux OS 흐름컨테이너를 잘 알기 위해서는 Linux에 대해서 먼저 알 필요가 있습니다.최초에 OS로 unix가 있었고,  한참 시간이 지나고 linux가 나왔어요. 그리고 이 linux를 기반으로 현재까지도 엄청 많은 배포판들이 만들어지고 있습니다.하지만, 다행이도 우리는 이 두 가지 배포판만 알고 있어도 충분해요.debian이랑 redhat 계열인데, debian linux는 커뮤니티용이라고 해서 무료고요. redhat linux는 redhat 이라는 기업에서 만들었고, 유료에요.쿠버네티스를 설치할 때도 이렇게 이 두가지 배포판을 기준으로 설치 가이드를 제공합니다. 데비안과 레드햇 계열에 대한 자세한 얘기는 강의 중에 설명드리고, 여기선 기업용으로 쓰는 redhat에 대해 좀 얘기를 해볼께요. redhat에서 linux 배포판이 만들어지는 순서가 있어요. 최초에는 fedora linux라고 해서 새로운 기능을 개발하는 버전이 있고, 이건 무료고요. 이 기능들이 안정화되면 redhat linux로 이름을 바꿔서 릴리즈를 합니다. 기업은 이걸 설치하면 유지보수 비용을 내야되는 유료 버전이고, redhat enterprise linux 앞자만 따서 RHEL, 렐 이라고도 통상 불러요. 그래서 이걸로 기업들이 설치를 하면 유지보수 비용을 내야 되는 유료 버전 이고, 그리고 이걸 복사해서 만든 게 centOS 배포판 이예요. rhel이랑 똑같이 안정화 버전인데, 무료로 쓸 수 있습니다.기업에서는 주로 redhat 계열을 많이 쓰고, 특히 centOS의 점유율이 높은데 centOS 8은 2021년에 지원을 종료 했고, centOS 7은 2024년도에 지원이 종료가 되거든요. 이 centOS가 종료되는 배경을 좀 말씀을 드리면 시장 점유율이 ubuntu가 압도적이고. 다음은 centOS랑 debian이 2, 3위를 왔다갔다 해요. redhat은 2%지만, 이 수치가 그래도 기업 배포판 중에 1위고요. 이 1위가 된 배경에는 사람들한테 centOS를 무료로 쓰게 해주면서 자연스럽게 redhat을 선택하게 하는 그런 전략이 있었거든요. 근데 현재 redhat은 IBM에 인수가 된 상태예요. 그리고 IBM의 새로운 전략은 centOS에 점유율을 rhel로 당기려는거 같아요.왜나하면 현재 redhat 배포판을 만드는 순서가 이렇게 변경됐거든요.처음엔 마찬가지로 fedora를 통해서 기능 개발을 하고, centOS대신 centOS Stream이라고해서 이 기능들을 테스트하는 배포판이 생겼어요. 테스트 배포판(테스트베드)이라고 생각을 하면 되는데 여전히 무료지만, 이 배포판에서는 바이너리 호환성 보장 안될 수 있다는 얘기를 해요. 무슨 내용인지 몰라도 이제 쓰면 안되나 싶은 생각이 들죠?그리고 테스트 과정이 끝나면, 안정화 버전인 Redhat Linux가 됩니다. 이렇게 배포판을 만드는 프로세스가 바꿨어요. 그래서 기존에 centOS를 쓰던 기업들은 앞으로 고민을 좀 해봐야 되는 게 지금 상황이고요. 아래와 같이 4가지 방법이 있는데 아래와 같습니다.이렇게 4가지 선택지 중에 전 4번을 선택을 했고, 이 강의에 실습 환경으로 사용이 되요. 저도 어떤 linux를 선택할까 고민을 많이 했는데, 1, 2번은 기업의 상황이라 제외를 하고, 타 OS로 ubuntu를 고민을 하다가 그래도 제가 가장 오래 사용을 했고, 문제가 생겼을 때 잘 가이드를 해드릴 수 있어야 하니까 4번, 새로운 복제본을 선택을 했습니다.그리고 AlmaLinux와 RockyLinux 중에서 Rocky Linux를 선택한 이유는 아래와 같아요.구글 트렌드에서 키워드 검색량 확인 (link)CentOS 공동설립자 중 한명 만들었음 (link)클라우드 서비스에서 VM 생성을 Rocky Linux로 하는 사례들 확인Github Watch/Fork/Start 비교 (rocky link), (alma link)  2. Container 흐름자, 이제 컨테이너에 대해서 얘기를 해 볼꺼예요. 지금까지 봐듯이 linux는 꾸준히 발전을 했고, 내부적으로도 많은 코어 기술들이 개발이 됐는데 그중 하나가 격리 기술이예요.chroot라고 해서 사용자 격리를 시작으로 파일이나 네트워크를 분리하는 기술들이 만들어 졌고요. 한참 지난 후에 cgroup이라고해서 각각에 App마다 cpu나 memory를 할당을 할 수 있게 됐어요. namespace는 보통 App 하나가 하나의 프로세스를 차지하거든요. 이 프로세스를 격리 시켜주는 기술이 만들어 지면서 우리는 이제 각각의 App을 소위 말하는 [독립적인 환경]에서 실행을 시킬 수 있게 됩니다.그리고 다음으로 이 기술들을 집약해서 정리한게 LXC라고 해서 linux container에 줄임말 이예요. 이 컨테이너의 어머니이자, 최초의 컨테이너죠. 그리고 이 기술을 기반으로 만들어진 이번엔 컨테이너에 대명사죠. Docker, 요즘은 위세가 많이 죽긴 했어요. 이전까지 컨테이너 기술은 저 같은 평범한 개발자들이 쓰기엔 좀 어려웠다면 docker는 이걸 누구나 쓰기 쉬운 형태로 만들었습니다. 요즘 잘 정리된 블로그 몇 개만 봐도 대강 이해해서 내 OS에 컨테이너를 띄울 수 있죠.docker가 나오고 rkt라고 rocket이라는 컨테이너가 나와요. docker가 보안에 안 좋은 점이 좀 있는데, 이 부분을 공략을 하면서 더 안정적인 컨테이너를 강조를 했고 실제 docker보다 성능도 더 좋다고 해요. docker가 보안에 안 좋은 점은 root권한으로 설치하고 실행을 해야 되기 때문인데, 현재는 rootless 설치 모드가 생겨서 보안이 강화가 됐습니다.한편 쿠버네티스는 점점 표준으로 정착이 되고 있고, 현재는 컨테이너간의 싸움 중입니다. 초반에 docker가 보안에 약하다는 것 까지는 사실 docker 대세에 크게 문제가 없었거든요. 시간이 지나면 충분히 보완 될꺼라는 기대도 있었고 실제로 보완이 됐죠. 근데 docker 위세가 조금씩 꺽이기 시작한 이유가 뭐냐면, 쿠버네티스에서 docker가 빠진 다는 얘기가 계속 있었어서 그래요. 그 이유는 docker가 쿠버네티스와 인터페이스가 잘 안 맞아서 그렇거든요. 물론 처음엔 docker를 메인으로 쿠버네티스가 만들어졌죠. 근데 쿠버네티스가 표준화가 될 수록 docker가 걸림돌이 되고 있는 상황이예요. 이제 누가 쿠버네티스랑 호환성이 좋은지가 컨테이너를 선택하는 중요한 결정요소가 됐습니다.그 이후에 나온 대표적인 컨테이너가 containerd랑 cri-o고요. containerd는 docker에서 컨테이너를 만들어주는 기능이 분리된 거예요. docker가 설치할 땐 간단해 보여도 엄청 많은 기능들이 녹아진 엔진이거든요. 그 큰 엔진에서 containerd 프로젝트만 분리 되서 나왔고 CNCF에 기부 됩니다. 번외로, docker는 현재 mirantis라는 회사에 인수된 상태예요. docker를 정말 많이 쓰지만 기술 투자 대비해서 수익이 큰 편은 아니었던 거 같아요. 그래서 mirantis라는 회사에 인수가 됐고 이 mirantis는 openstack 프로젝트를 하고 있는 회사 거든요. 이 openstack이 뭐냐면, kubernetes 이전에, 가상화에 대세라고 하긴 좀 그렇고, 가장 큰 가능성으로 가상화 시장을 선도한게 openstack 이예요. 저도 개인적으로 한 3년 정도 openstack 관련된 일을 했었고, 그래서 다음 가상화를 설명하는 강의에서 최대한 재미있게 얘기를 해 드릴께요. 여튼 docker가 mirantis에 인수된 이후부터 이 kubernetes 인터페이스를 잘 맞추려고 하고 있기 때문에 쿠버네티스에서 docker는 빠지진 않게 됩니다. 3. Container Orchestration과 Container 흐름강의 영상에서 컨테이너 오케스트레이션(쿠버네티스)과 컨테이너(컨테이너 런타임) 간에 한 단계 더 깊은 흐름을 이야기 합니다.가장 핵심은 쿠버네티스의 kubelet 변화와 그리고 이에 따른 컨테이너 런타임들 간의 흐름이예요. 바로 CRI가 어떤 배경에서 만들어졌고, 쿠버네티스 버전이 올라가면서 CRI가 어떤 방향으로 바뀌는지, 그리고 그에 따른 컨테이너 런타임들 간의 변화를 설명드립니다. 그리고 컨테이너에서 절대 빼놓으면 안되는 OCI가 있습니다. 컨테이너 표준인데, 컨테이너 런타임들은 이걸 잘 지키고 있기 때문에, 우리는 런타임을 바꾸더라도 기존에 만들었던 이미지를 그대로 사용할 수 있어요  블로그는 여기까지고요. 강의가 오픈 되면 링크 걸어 놓을께요.좋은 하루되세요!  해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 :https://inf.run/Acobj 좋아요 ​♡는 저에게 큰 힘이 됩니다 :) 

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopscontainer컨테이너한방정리

일프로

[kubernetes] 실무에서 느껴본 쿠버네티스가 정말 편한 이유 #5

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 저는 개발자로써 SI 프로젝트를 많이 했습니다. 그리고 제가 겪은 SI에 대해서 얘기 드리면..일단 개발에만 몰두할 수 있는 시간은 별로 없어요. 제안서 쓰고, 업무 프로세스 분석하고, 단계별 문서를 만들고 상황에 따라 인프라 구축도 하고, DB부터 Web Front까지.. 프로젝트 오픈에 필요한 많은 걸 경험해 봤어요.물론 이것도 하다 보면 익숙해지는 부분도 있지만 그래도 매번 SI프로젝트를 힘들게 만드는 요인이 뭐냐면하나는 매번 다른 업무 프로세스에요. 고객사마다 업무 프로세스가 다르니까 매번 새 업무를 분석하느라 고생을 하게 되고요. 그리고 변화가 빠른 웹 기술이에요. 웹 분야는 발전 속도가 빠르고 신 기술이 많아서 프로젝트를 할 때마다 같은 기술로 웹 페이지를 만들어 본 적이 별로 없었던 것 같아요. 그래서 매번 새로운 기술을 공부해야 됐고. 마지막으로 다양한 기술 솔루션 적용인데, 모니터링이나 로깅, 암호와 같은 솔루션이 고객사마다 쓰는 제품들이 다르고요. 비용 절약 때문에 개발자가 직접 해야 되는 경우도 비일비재해요. 그래서 이것도 매번 새 솔루션을 적용하는 법을 익혀야 됐습니다.더 많지만 이렇게 이번 프로젝트에서 고생을 해서 기술을 익혀도 다음 프로젝트는 또 고생을 하게 되더군요.하지만, 개발자가 아닌 쿠버네티스 엔지니어로서 SI프로젝트는 할만 했습니다.무엇보다 프로젝트가 반복될 수록 일은 더욱 쉬워졌는데, 이번 강의에서 [쿠버네티스 표준 생태계로 편해진 IT인프라 구축], [쿠버네티스 기능으로 편해진 서비스 안정화], [인프라 환경 관리의 코드화]를 주제로 그 이유를 자세히 설명 드려요.쿠버네티스 표준 생태계로 편해진 IT인프라 구축쿠버네티스가 나온 지 10 년도 안 됐는데, 현재 이렇게 많은 제품들이 쿠버네티스 생태계 위에서 돌아가요.IT에 관련된 모든 회사가 쿠버네티스와 컨테이너에 진입을 했다고 해도 과언이 아닐 정도인데, 이미 많은 회사들은 컨테이너가 미래에 인프라가 될 거라는 걸 예상했고 너도나도 이 시장의 넘버원이 되려고 뛰어 들었어요. 그 결과 정말 짧은 시간만에 쿠버네티스 기반의 IT 생태계가 이렇게 폭발적으로 커졌습니다.여러분 지금 기업에서 대부분 자바로 개발을 하잖아요. 자바가 95년도에 처음 만들어졌고 10년 뒤에 이걸로 스프링이 나왔어요. 그리고 또 5년이 지나서야 확산이 되기 시작한 건데, 그에 비해 쿠버네티스는 정말 이례적이라고 할 수가 있죠.근데 이 그림을 보면, 아 이제 늦었나? 쿠버네티스를 하려면 이렇게 많이 알아야 돼? 라고 오해를 할 수가 있을 것 같아요. 뭔가 많아 보일 순 있는데 점점 제가 단순화를 시킬 거니까 걱정 마시고요.CNCF에서 이 클라우드 생태계를 영역별로 카테고리화 시켰는데,[개발]은 기존부터 해왔던 App 개발에서 배포까지 써야되는 기술들 이고요. [오케스트레이션 / 매니징]은 이 App을 마이크로 서비스로 만들 때 쓰면 좋은 기술들이에요. 그리고 [플랫폼과 런타임]은 이 App을 클라우드로 올릴 때 주로 사용되는 기술들이 많고요. 그리고 [프로비저닝이랑 분석]은 실제 프로젝트에서 써야 되는 기술들이 있어요.만약에 프로젝트에서 App을 마이크로 서비스로 개발하고 클라우드까지 올린다면 여기 있는 카테고리를 다 알아야 되고 근데 요즘은 이런 프로젝트가 대부분이죠 :)그나마 불필요하다고 생각하는 부분은 그리고 밑에 [스페셜]은 쿠버네티스 관련 업체들이랑 교육 파트너고요. [서비스]랑 분석 쪽에 [카오스 엔지니어링]이랑 [최적화]부분은 메인 영역은 아니라서 과감히 빼버리겠습니다. 그리고 전체 그림을 다시 보면..아까보단 좀 나아진 거 같나요?이미지들이 살짝 눈에 보이는 거 같기도 하고요. 그래도 아직 쿠버네티스를 하기 싫어지는 그림이에요. 여기서 이제 디테일하게 줄여나가 보겠습니다. CNCF에 기여된 프로젝트는 성숙도에 따라서 이렇게 4가지 종류가 있는데, Sandbox는 아직 실험 단계라서 우리가 안 쓰게 될 확률이 커요. 그리고 그 밑에 Archived는 프로젝트가 비활성화 된 거에요. 그래서 더 이상 기술 지원이 없는 프로젝트니까 이 두 가지를 빼고요.CNCF에서 성숙도가 높다고 우리가 많이 쓰고 있는 건 아니거든요. 그래서 Graduated지만  Github에 Stars 수가 낮은 건 제외를 하고 Incubating 이지만 Stars 수가 높은 건 포함해서 보면..이정도가 있네요. 그리고 CNCF에 기여된 프로젝트 외에 CNCF 멤버와 비멤버 제품들도 있어요. 멤버와 비멤버의 차이는 CNCF에 회비를 내면서 제품 홍보나 등급별로 혜택을 받을 수 있나없나의 차이일뿐이고, 그래서 비멤버라도 표준 생태계에 영향력 있는 제품들이 많습니다.그래서 CNCF 멤버/비멤버 제품들 중 Github에 Stars 수가 높은 걸 골라보면.. 이 정도로 정리가 돼요. 이제 이렇게 추린 내용을 다시 이쁘게 정리해보겠습니다. 참고로 제가 짬으로 몇 개 추가/삭제한 것도 있어요.CNCF landscape 중 선별 기준CNCF 프로젝트 : Graduated Projects (Github Stars 낮음 제외), Incubating Projects (Github Stars 높음 추가), Sandbox Projects (X), Archived Projects (X)CNCF 멤버/비멤버 제품 : 깃허브 Stars 높음 추가, 일프로 임의 추가참고 링크 : CNCF (link), CNCF landscape (link) 이제 좀 그림이 보이기도 하고, 안구 정화가 되죠?눈에 잡히는 IT생태계를 보여 드리려고 이렇게 정리를 해 봤는데, 사실 CNCF를 졸업했고 멤버가 어떻고는 중요하지 않아요. 그리고 제가 이 정리된 그림을 먼저 보여 드려도 되는데 이런 선별 과정까지 보여 드린 이유가 있습니다.이 오픈 소스들을 공부하게 될 때 이것만 잘 깊이 있게 보면 좋은데 갑자기 누가 요즘 뭐가 좋다더라 이런 얘기를 하면 자기가 모르는 게 있으면 괜히 그게 커보이고 해야될 것 같은 기분이 들죠? 그래서 지금 공부에 집중력이 떨어질 수가 있어요. 그렇기 때문에 여기 이 제품들은 정말 많은 오픈 소스들 중에 대표이고 일단 처음엔 여기에만 집중해도 충분하다는 것을 보여 드리려고 이렇게 선별과정을 보여 드린거에요.물론 이것도 적지않죠?그리고 강의 영상 마지막에 쿠버네티스 엔지니어가 되려면 이 많은 내용들을 어떻게 공부해야 되는지 이 그림으로 설명드릴께요.   쿠버네티스 기능으로 편해진 서비스 안정화 강의에서는 쿠버네티스가 편한 이유 중 두 번째로 기존 VM 환경과 쿠버네티스 환경의 차이를 얘기드려요. 기존 환경에서 여러 담당자들이 수동으로 설정해야 했던 일들을 쿠버네티스 환경에서는 쿠버네티스 엔지니어 한명이 한번에 할 수 있게 되거든요.  모니터링 설치이젠 모니터링 설치하는 방법도 너무 쉽죠?카페 설치 링크 (link)참고 링크 : grafana docs (link) / dashboard (link), prometheus install (link) / docs (link), loki-stack install (link) / docs (link)기능 실습그리고 강의영상에서 쿠버네티스 대표 기능들을 실습해 봅니다.카페 실습 링크 (link)인프라 환경 관리의 코드화마지막으로 쿠버네티스 관리 환경의 코드화인데, 인프라 설정을 수동으로 하는 거랑 파드에 인프라 설정이 코드로 들어가서 자동으로 되는 건 엄청난 차이고요. 이 차이가 인프라 환경 관리를 정말 편하게 해줍니다.쿠버네티스, 인프라 환경 관리의 장점인프라에 대한 History 관리가 편해짐인프라 작업 추적 가능인프라 환경별 파일 생성 (시간 있을 때 미리 구성 가능, 작업은 Copy & Paste)인프라 반복 작업 x, 퀄리티 향상에 집중새 인프라 작업시 이전 경험을 녹인 코드 활용블로그는 여기까지고 강의가 오픈 되면 링크 걸어 놓을게요^^굿나잇! ps. 매너가 좋아요♡를 만든다 :)

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopscontainer쿠버네티스편한이유

일프로

Application 기능으로 이해하기-Configmap, Secret #7-2

 Configmap, Secret 개념 설명 Configmap과 Secret은 Pod에 바로 연결되고요. Object에 속성들을 보면 둘 다 데이터를 담을 수 있어요. 그래서 사용자가 데이터를 넣고 Pod에 값을 주입 시킬 수가 있는데, Pod에 연결되는 속성 이름을 보면 어떤 방식으로 들어가는지 알 수 있습니다.envFrom은 Pod안에 환경변수로 들어가게 하는 속성이고, 그래서 Configmap을 연결하고 Pod 안에 들어가서 env라는 명령을 쳐보면, 이 Configmap의 data가 주입 된 걸 볼 수가 있어요.Volume은 Pod와 특정 저장소를 연결하는 속성이고, Secret을 연결하고 Pod 안에 들어가서 마운팅 된 Path를 조회해보면, 이 Secret의 stringData가 있는 걸 볼 수가 있고요.특별히 어려운 내용은 없죠?아무리 처음 쿠버네티스를 공부하시는 분이더라도 환경변수와 마운팅의 개념은 기존에도 써왔기 때문에 쉽게 이해할 수 있어요. 그리고 Secret은 이름 부터가 뭔가 비밀스럽게 데이터를 처리해 줄 것 같은 느낌이 있으니까. 쿠버네티스에서 데이터에 어느 정도 보안을 적용해주는 가보다 생각할 수 있죠. Configmap 기능 설명Configmap의 데이터가  Pod에 환경변수로 들어간다고 얘기했는데, 환경변수에 들어가는 값은 다양하고요. Data에 내용을 보면 Key, Value 형식으로 spring-profiles-active에 dev가 있죠? 환경 변수로 흔히 들어가는 값인데, 인프라에 다양한 환경 개발/검증/운영 등에 환경이 있고, 이 App이 어느 환경에서 돌아가는 건지 App이 기동되는 시점에 알려주기 위한 변수에요.다음 환경변수에는 Application Role이라는게 있고. 말 그대로 이 App에 역할을 지정하는 건데, 예를 들어 한 App에 3가지 기능이 있는데, App 하나만 띄어서 모든 기능을 다 쓰기도 하고요. 스케일링 모드라고 해서 이 App을 기능별로 3개를 띄우고 부하가 많은 기능만 별도로 더 띄워요. 요즘은 마이크로 서비스 아케텍쳐를 반영해서 이렇게 만들어진 오픈소스도 많습니다.밑에 postgresql-filepath는 또 다른 예인데, 이건 여기 Secret 데이터로 연결할 파일에 경로에요. 이 경로는 Pod에 mountPath에서 정하거든요. 그리고 이 경로 DB 정보를 환경변수로 주면, App은 기동 될 때 이걸 읽어서 DB에 접속할 수 있도록 로직이 되있는데, 이 경로를 이렇게 환경변수로 입력해야 Pod에서 이 경로를 바꾸게 됐을 때 App을 다시 빌드해서 새 이미지를 만들지 않고, Configmap만 수정해서 App이 변경된 경로를 인식할 수 있도록 할 수 있겠죠?이렇게 외부에 변경되는 환경이 생길 때, 그걸 App에 전달해 주기 위한 값들도 있는거고, App 내부적으로 기동되는 시점에 이 환경변수 값에 따라 다르게 처리되는 로직이 있어야 되요.자 그럼 이제 이 내용을 Pod랑 연결을 하고 Pod가 생성됐을 때 상황을 얘기 해볼께요. 처음에 Configmap에 있는 data의 모든 내용이 컨테이너 내부 환경에 환경변수로 주입이 됩니다. 그리고 이 이미지를 만들 때 이런 자바파일 실행 명령을 넣어놨거든요. 이미지를 만드는건 sprint2에서 배울꺼고 이 명령이 컨테이너 생성 후에 자동으로 동작하게 되고, 이때 환경변수 값이 들어가는데, 만약에 환경변수로 spring-profiles-active가 없었다면 null값이 들어가게 되요. 밑에 Secret의 기능 설명과 두 기능에 대한 동작 확인은 강의 영상으로 설명 드리고요. Secret 기능 설명동작 확인영역 파괴의 주범 ConfigMap기존 VM환경이랑 쿠버네티스 환경의 배포 차이를 보면서 영역 파괴의 주범인 ConfigMap에 대한 얘기를 해볼께요. 각 환경마다 Pod가 만들어지고, 이 Pod에 들어가는 컨테이너는 dockerhub에서 모두 같은 이미지를 다운 받았어요. 하지만 환경마다 다른 값을 주려고 각각에 Configmap을 만들죠. 그리고 이미지 안에 변수값을 받아서 실행하는 명령어가 들어 있어요.이제 개발환경을 보면 이렇게 spring으로 개발을 하고 여기서 [개발자]가 Properties 파일들이 만들고 관리를 해요. 그리고 Github로 소스를 커밋하면, 여기서부터는 [데브옵스 엔지니어]가 Jenkins에서 이 소스를 받아서 파이프라인을 구성하는데, 소스 빌드와 컨테이너 빌드 과정에서 컨테이너 이미지가 도커 허브로 올라가요. 그리고 컨테이너 빌드 후에 개발환경을 바로 이어서 배포를 할 수 있고, qa와 prod는 필요할 때 배포 버튼을 따로 누르게 구성해 놨다고 해보겠습니다.그럼 VM 환경의 배포는 어떤지 보겠습니다.개발 환경과 CI/CD 환경은 비슷하고, [인프라 담당자]가 환경별로 서버를 세팅해 놓습니다. 각 환경별로 OpenJDK도 설치해 놓고요. 이 과정에서 VM 내부에서 사용할 환경변수들을 관리를 하죠. 그리고 배포는 이렇게 되는데, Jar 패키지 파일을 VM 환경에 복사 해놓고, 실행 명령을 직접 날리는데 이때 [데브옵스 관리자]이 App에 환경이나 목적에 맞는 변수를 넣어요. 그리고 환경이나 목적에 맞게 변수값이 채워진 스크립트를 실행시킵니다.그래서 여기까지 보면 쿠버네티스 환경 이전에는 각자의 영역에서 담당자들이 관리하는 환경변수들이 있었는데, 쿠버네티스가 나오고 이 ConfigMap에서 모든 역할을 다 할 수가 있게 된 거죠. 그래서 ConfigMap을 담당하는 사람이 다른 영역을 넘나들 수 있게 되고 이런 소지를 주는 Configmap을 좀 과격한 표현으로 영역 파괴의 주범이라고 표현을 한 건데.물론 이 전체를 혼자 다하는 슈퍼 개발자도 있겠지만, 프로젝트가 클 수록 각 영역에 담당자들이 있고요. 현재 이 모두가 쿠버네티스를 다 다룰 줄 아는게 아니기 때문에 만약 개발자가 쿠버네티스를 잘하면, 이 Properties 값들 중에 Pod를 재생성하기만 하면, 다시 빌드하지 않고 바로 반영될 수 있는 값들을 많이 집어넣겠죠? 그러다가 다른 영역에 있는 값들도 넣으면서 일을 주도하게 될꺼예요.하지만 다른 담당자 입장에서는 본인의 영역을 침범 당한다고 생각할 수 있는데, 참 별거 아닌 기능이지만, 여러 영역에 걸쳐 있는 기능이기 때문에 의견을 잘 조율을 해서 써야 되는 점 주의하시길 바랄께요. 이름 때문에 기대가 너무 컸던 Secret 해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 :https://inf.run/f2xSR ps. 좋아요♡는 준 만큼 받는다 :)

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopsConfigmapSecret

일프로

[쿠어클#4] 쿠버네티스 무게감 있게 설치하기

안녕하세요. 쿠버네티스 제대로 시작하기 첫 강의로 쿠버네티스 환경 구축을 해보겠습니다.아래 정말 쉽고 빠르게 쿠버네티스를 설치하는 방법이 있어요! 쿠버네티스(v.1.27.2) 쉽고 빠르게 설치하는 방법Virtualbox 설치 (link)Vagrant 설치 (link)Vagrant 스크립트 실행 (윈도우 > 실행 > cmd > 확인)# Vagrant 폴더 생성 C:\Users\사용자> mkdir k8s C:\Users\사용자> cd k8s # Vagrant 스크립트 다운로드 C:\Users\사용자\k8s> curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/vagrant-2.3.4/Vagrantfile # Rocky Linux Repo 세팅 C:\Users\사용자\k8s> curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/vagrant-2.3.4/rockylinux-repo.json C:\Users\사용자\k8s> vagrant box add rockylinux-repo.json # Vagrant Disk 설정 Plugin 설치 C:\Users\사용자\k8s> vagrant plugin install vagrant-disksize # Vagrant 실행 (VM생성) C:\Users\사용자\k8s> vagrant upMobaXterm 설치 (link)Master 원격 접속 : 192.168.56.30:22 (root/vagrant)Pod 확인kubectl get pods -A대시보드 접속 URI : https://192.168.56.30:30000/#/login FAQ : virtualbox 설치 안될 때 (link), vagrant up 안될 때 (link), dashboard 관련 (link), virtualbox Host-Only Network cidr 변경 (link)Cafe : 쿠버네티스 빠른 설치 카페 참조 (link)  정말 쉽죠?하지만 저는 쿠버네티스 설치를 쉽고 빠르게 한다고 해서 좋은 건 아니라고 생각합니다. 쿠버네티스 오브젝트들, Pod나 Service를 공부하면서 개념이나 기능만으로 이 기술을 이해하는데는 한계가 있거든요. 쿠버네티스 자체 구성을 조금은 알고 이 개념들을 공부하는게  더 잘 이해가 잘 되요. 그리고 쿠버네티스 구성에 대한 부분들은 쿠버네티스를 설치할 때 가장 배우기 좋은 내용입니다.그렇기 때문에 Pod를 빨리 만들어보고 싶은 마음도 이해하지만 쿠버네티스를 제대로 공부하고 싶으신 분이시라면, 이번 설치 강의를 통해서 쿠버네티스 구성을 꼭 이해하고 넘어가길 권해드려요. 아니 꼭 이렇게 하셔야되요! 쿠버네티스 무게감 있게 설치하는 방법 1/2먼저 설명에 시작은 내 PC에 Virtaulbox랑 Vagrant를 설치한 상태고요. 제가 만든 Vagrant 설치 스크립트를 받으면 위에 내용이 나와요. 그리고 이 스크립트는 크게 [Virtualbox로 Rocky Linux를 생성]하는 파트랑 [kubernetes를 설치]하는 파트로 구분되는데 먼저 Virtualbox로 VM을 생성하는 걸 설명 드릴께요. 우측 스크립트를 위에서 부터 보면, OS를  [rocky linux 8]버전으로 설치하라는 내용이고, 처음 설치할 때는 이 이미지를 다운 받는데 시간이 좀 걸려요. 그리고 [master-node]는 Virtualbox 입장에서 생성된 VM에 이름을 붙여주는 부분인데, Virtualbox UI 상으로 봤을 때 보이는 이름 이예요. 그리고 밑에 hostname 을 지정하는 부분이 있고, [k8s-master] 라고 넣으면, 나중에 원격접속으로, 리눅스에 들어 갔을 때, 나오는 호스트 이름입니다.  그리고 밑에 [private_network]는 virtualbox에 Host-Only Network 라고 해서, 내 PC 에서만 사용할 수 있는 네트워크망을 만들어 주고, 스크립트에서 IP를 주면 내 Linux에 그 IP가 할당됩니다. 그래서 우리는 내 PC에서 이 IP로 원격 접속을 하면 Linux OS에 들어갈 수 있게 되는 거고. 브라우저를 통해서 kubernetes dashboard에 접속 할 수도 있게 되요. 이렇게 이 스크립트 한 줄로 Host-Only Network가 만들어지고 IP가 할당 되는데, 스크립트에 넣지 않아도 Vagrant가 기본적으로 만들어주는 네트워크가 있어요.바로 NAT 라는 네트워크고 입니다. IP도 알아서  할당 돼요. 이 NAT의 역할은 내 VM을 외부 인터넷이랑 연결 시켜줍니다. 그래서 이따가 쿠버네티스를 설치할 때 필요한 패키지들을 받는데 사용하고요 실제 내 PC에 할당된 Network는 공유기에서 할당 받은 상태죠. 제 PC의 경우 [192.168.219.100]의 주소를 할당 받았고요. 제 공유기는 192.168.219까지는 고정이고, 뒤에 4번째 자리는 1~255까지 만들 수 있는데 자동으로 100이 할당 된 거예요.근데 Host-Only Network를 보면 디폴트로 192.168.56까지 고정이고, 네 번째는 1~255까지 만들 수 있는 네트워크 입니다.네트워크를 생성할 때 cidr 을 정하면, 이렇게 지정한 범위 내에서 IP가 할당 되는데, 네트워크 원리는 잘 몰라도, 최소한 대역들이 겹치면 안된다는 건 알고 계셔야 돼요. 겹치게 되면 내 공유기랑 Virtualbox가 똑같은 IP 를 만들 수 있게 돼서 IP 충돌이 나요. 근데 이 공유기 환경이 개인 마다 다른 부분이라서 혹시 원격 접속이 안되시는 분은 본인에 Network 대역을 확인해 보시고요. 부득이한 경우 Host-Only Network에 cidr 을 수정해 주면 돼요. 제가 카페에 방법을 올려 놓을께요. 여기까지 네트워크에 대한 설명이 이었습니다.이번엔 자원(resource)을 볼께요.스크립트를 보면 VM에는 Memory는 4G고 CPU는 4Core를 잡았어요. 제 PC에 자원을 보면 제 PC는 4Core, 16G Memory거든요. 여기서 분명 Memroy는 내 자원에서 나눠 주는 거라 VM에 자원 할당한 게 이해 되는데, CPU를 이렇게 다 줘버리면 내 PC는 괜찮을까 걱정되는 분이 계실 거예요.근데 이 두 자원의 속성을 보면 Memory는 서로 할당된 공간을 침범하면 안돼요. A프로그램이 쓴 메모리 공간에 B프로그램이 침범해서 내용을 바꿔버리면 안되잖아요? 그래서 꼭 자원을 철저하게 분할해서 써야 되는 성격이라면, CPU는 필요로 하는 순간에 서로 나눠 쓰는 자원이예요. 그래서 현재 이 CPU 할당에 의미는 내 PC CPU가 필요할 때는 4 Core를 다 쓸 수도 있고. VM에서도 필요할 때도 최대 4Core를 다 쓸 수 있도록 설정 한 건데, 만약 둘 다 CPU가 필요한 상황이라면 이 4core 자원을 나눠쓰고요. 대신 처리속도는 좀 느려지지만 문제는 없어요.참고로 쿠버네티스 설치 문서에 권고하는 CPU는 2Core 이상입니다.이 CPU와 Memory에 대해서 제가 4 Core를 준 이유와 각자가 작업 유형에 맞게 변경을 하시라고 자세히 설명 드렸지만, 이 두 자원에 대한 성격은 쿠버네티스에도 Pod에 자원을 할당하거나 Pod가 늘어나는 설정을 할 때, 정말 중요하게 고려해야 되는 포인트라서 이 자원에 성격을 자세히 얘기 해봤어요. 쿠버네티스 무게감 있게 설치하는 방법 1/2 [구간별상태확인]카페(아직 공사중)에 들어가보면 각 포인트에 대해서 잘 설치됐는지 확인 볼 수 있어요. (link)  쿠버네티스 무게감 있게 설치하는 방법 2/2위 내용은 강의의 메인으로 쿠버네티스 설치인데 강의에서 자세히 설명 드립니다. 지금까지 설명 드린 강도랑 내용보다 좀 더 깊어지는 점 주의 드려요.쿠버네티스 설치는 확실히 쿠버네티스 문서(link)를 보는게 좋습니다. 내가 설치하려는 버전이 있는데 블로그에서 다른 버전이나 최신버전 설치를 보게 되면, 미묘하게 잘 안되는 부분들이 생기거든요. 그래서 그 원인을 찾는데 시간을 더 쓰는 경우도 생기는데, 쿠버네티스는 컨테이너 한방 정리에서 히스토리로 봤듯이 내부적인 변경사항들이 많아서 그래요. 그래서 쿠버네티스 문서에서 필요한 버전별로 설치 가이드를 보는 게 좋고 쿠버네티스 문서가 한글화도 잘 되있거든요. 전 이 한글화 된 문서를 정말 열심히 보고 있고 이 한글화 작업하시는 분들께 항상 감사 드리는 마음입니다. 이 강의 설명의 목적은 쿠버네티스 설치 문서를 함께 공부하면서, 수강생 분들이 이 강의를 잘 들으면 이 강의에 설치 뿐만 아니라 다른 버전으로 쿠버네티스를 설치하거나 컨테이너 런타임을 바꿔보고 싶을 때 스스로 찾아서 할 수 있는 능력을 길러 드리는 거예요. 쿠버네티스 무게감 있게 설치하는 방법 2/2 [구간별상태확인]마찬가지로 카페(아직 공사중)에 들어가보면 각 포인트에 대해서 잘 설치됐는지 확인 볼 수 있어요 (link) 나중에 다른 사람과 똑같이 쉽게 쿠버네티스를 설치하더라도 이렇게 공부하면 한번에 클릭이 좀 더 무게감 있는 사람이 됩니다. 가끔 보면 그냥 빨리빨리 버튼 누르고 진행할 수 있는 상황에도 버튼 하나 누를때마다 한참 생각했다가 누르는 사람이 주변에 있지 않나요? 그 사람이 아는 게 많을 수록 이 버튼 누르는 속도는 더 느려져요. 이 사람은 겉으로는 답답해 보일 수 있는데, 머릿속에는 엄청 많은 정보들이 스쳐 지나가고 있는 겁니다.여러분도 이렇게 되시길 응원 드려요! 그럼 이번 블로그는  여기까지고요, 해당 강의에서는 실습과 더불어 추가적으로 아래 내용들에 대해서 더 다룹니다 😀[쿠버네티스 어나더 클래스] : https://inf.run/unreT  좋아요 ​♡는 저에게 큰 힘이 됩니다 :)   

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopscontainer쿠버네티스설치

일프로

[kubernetes] 강의 소개 #1

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요! 강의 링크 : https://inf.run/NzKy 제가 이전 쿠버네티스 강의를 만든 지 벌써 4년 정도가 지났는데, 그동안 저는 현업에서 계속 프로젝트를 하느라 바쁘게 지내고 있었어요. 최근 여유가 생겨서 이렇게 다시 강의 만들 기회를 가질 수 있게 됐고, 제일 먼저, 어떤 강의를 만들지 고민을 많이 했습니다.​쿠버네티스가 나온 지 적지 않은 시간이 지났고, 인터넷이나 많은 책들을 통해서 필요한 내용을 쉽게 찾아볼 수 있게 됐죠. 그리고 그 내용들을 보면 이제 정말 쿠버네티스를 잘 아는 사람들이 많아 졌구나를 느끼는데 막상 프로젝트를 하다보면 주변에 쿠버네티스를 생소하게 생각하는 분들이 아직도 훨씬 많습니다.그리고 시도를 했다가 포기를 하시는 분들도 더러 봤는데 정보는 많지만 여전히 쿠버네티스가 새로 시작하는 사람들에게 큰 진입 장벽이 있는 것 같아요.​그래서 저는 기존보다 더 난이도 있는 강의를 만드는 것보다 입문자가 더 쉽고 재미있게 쿠버네티스를 시작할 수 있는 강의를 만드는 게 더 의미 있는 일이라고 생각을 했고, 처음엔 저도 쿠버네티스를 시작하면서 새로운 개념들을 이해한 다음 다 중요하고 써먹어야 할 것 같아서 프로젝트에 적용을 했다가 다시 걷어내는 일들을 반복을 했는데 이건 쿠버네티스 기술이 워낙에 광범위하기 때문에 누구나 겪게 되는 문제이자 반면에 쿠버네티스를 포기하게 만드는 원인인 것 같아요.​전 이제 그동안의 경험으로 어떤게 중요하고, 어떤 건 적당히만 알면 되고, 또 어떤 건 잘 안 써서 몰라도 되는 건지에 대한 감이 좀 생겼는데, 이 강의는 기존 A~Z식의 얇고 넓은 범위의 강의가 아닌 하나를 공부를 하더라도 그 개념에 대한 배경 지식을 충분히 이해하고 깊이 있는 실력을 만들어 주는 강의를 만들어 보려고 해요.그래서 강의 제목에 이전 강의와는 또 다른 방식의 강의라는 의미로 어나더 클래스라는 이름을 붙여 봤습니다.​ 강의 주제먼저 강의 주제로 전체적인 제 강의의 컨셉을 설명 드리면, 쿠버네티스 어나더 클래스는 총 3개의 Sprint로 나눠져 있고 각각의 Sprint는 다른 주제를 가지고, 새 강의로 만들어져요.​그래서 결국 모든 강의를 다 들으시려면 세 번의 수강 신청을 하셔야 하는 건데, 이렇게 나누는 이유는 앞에서도 말씀드렸다시피 이제 쿠버네티스를 어느 정도 잘 아는 분들이 많아졌기 때문에 제 강의에서 필요한 부분만 듣고 싶은 분들도 분명히 계실 거예요. 그래서 강의 설명을 잘 보시고 내가 필요한 내용 인지를 판단해서 조금이라도 낮은 가격으로 필요한 내용을 수강할 수 있게 하기 위해서 입니다.​저도 각 강의에 어떤 내용들이 담겨져 있는지에 대해서 최대한 알려 드리도록 노력을 할게요. 그리고 Sprint가 보통 2주를 얘기를 하는데 여러분들이 Sprint 강의 하나를 들을 때 최소 2주는 잡고 공부를 했으면 해요. 5시간 정도의 강의 분량을 2주 동안 듣는 방법은 바로 복습을 해야 된다는 거구요. 강의 내용 중에도 제가 계속 복습을 강조를 할 건데 그 방법에 대해서는 강의를 통해서 더 말씀을 드릴게요.​그리고 Sprint마다 이름이 있어요. 모두 북극에 사는 귀여운 동물들인데 사실 제 입장에서는 이 Sprint 하나를 제작하는데 두 달에서 세 달 정도 걸리는 소규모 프로젝트거든요. 그래서 제가 강의 하나하나에 의미를 부여하기 위해서 이렇게 이름을 지어 봤습니다. ​현재 여러분께서는 Sprint1의 Polar Rabbit의 강의 소개를 보고 계십니다.​다음으로 이 강의에 수강 대상이 좀 많죠? 절대로 아무 생각 없이 제가 아는 IT직군을 모두 때려 넣은 건 아니구요. 이 분들이 수강을 하셔야 되는 이유는 뒤에서 별도로 말씀을 드릴 건데, 일단 대상군이 많다는 건 입문자가 들을 수 있는 난이도 라고 보시면 되고, 이 세 개의 Sprint 전체가 그렇고 저는 이 전체에 대한 난이도를 [지상편]이라고 붙였습니다. 그럼 이제 다음편으로 조금 더 높은 수준의 난이도가 있겠죠? ​​점점 깊게 들어가는 의미로 [해수편]과 [심해편] 그리고 [해연편]까지 생각을 하고 있구요. 각각에 수강 대상은 다른데, 저는 최근까지 큰 프로젝트에서 쿠버네티스 파트에 아키텍트 역할을 해왔고요. 최대한 제가 했던 일까지 모두 강의로 만드는 게 최종 목표입니다. ​강의 소개​이제 수강 대상과 이 대상들이 쿠버네티스를 왜 알아야 되는지 얘기를 해볼게요. ​채용 우대사항에 항목들은 점점 많아지고 있습니다. 이 우대사항은 그 팀에서 주로 쓰는 개발환경을 나열해 놓기 마련인데, 그만큼 IT시스템이 나날이 복잡해지고 있다는 거죠. 그리고 여기에 쿠버네티스가 직군을 막론하고 한 자리를 차지하고 있는 걸 볼 수 있고요. 그래서 이젠 구직할 때 쿠버네티스도 알아야 하는데, 우대사항까지 이렇게 챙겨야 되나 싶겠지만, 요즘은 고스펙 경쟁 시대라 구직자 분들께 부담을 드리는 것 같아 죄송하지만 어느정도는 알아야 한다고 말씀드릴께요. 이들에게는 각자의 영역이 있지만 쿠버네티스는 어느 특정 영역에 한정되지 않아요. IT 전체에 퍼져서 매력적인 기능들을 제공하고 있는데요. 그래서 개발자가 쿠버네티스에 한번 발 담구다 보면 어느새 인프라의 스토리지를 밤새 공부하고 있는 자신을 발견하기도 합니다.​그래서 저는 쿠버네티스가 영역 파괴자라고 불러도 과언이 아니라고 생각하고 각 영역에 대한 경계를 많이 모호해지게 만들었다고 보는데, 그만큼 쿠버네티스를 잘 모르면 누군가에 의해서 내 영역이 흔들릴 수가 있게 된다는 거죠. 그래서 쿠버네티스를 더 잘 알아야 각자의 입지를 더 튼튼하게 다질 수 있다고 말씀드리고요.기존 환경을 쿠버네티스 환경으로 전환하는 큰 프로젝트들이 많아지고 있고, 물론 쿠버네티스 환경이 구축되면 장애에 대해 좀 더 여유가 생기는 건 사실이지만, Container나 Pod 등 새로운 용어나 기술사용 들이 기존 시스템과 많이 다르긴 합니다.​그렇기 때문에 이런 새로운 환경을 갑자기 받아들이는데 부담이 있을 수 밖에 없어요. 근데 구축팀 입장에서 프로젝트 오픈에 허덕이다 보면 중간중간 운영팀에 교육을 하기 힘든 경우가 많은데, 이때 운영팀에 팀원들은 이 시스템을 받는 것에 대한 걱정이 많아지면서 조금씩 이직에 대한 고민을 합니다. 하지만 이직은 선택을 지연시킬 뿐이예요. 어차피 쿠버네티스 환경은 계속 많아질 것이기 때문에 나중에 또 같은 상황으로 이직을 고민하게 될 수 있습니다.​그래서 가장 좋은 건 부담이 생기기 전에 미리미리 쿠버네티스를 공부해 놓고, 프로젝트가 진행되는 걸 편하게 지켜보면서 내 입맛에 맞는 요구사항들을 쏟아내는 거겠죠? ​이미 쿠버네티스를 도입해서 비용을 절감했다는 입소문이 퍼지기 시작했고, 너도나도 쿠버네티스를 적용해보려는 시도들이 많아 졌습니다. 근데 자사에 운영 인력이 부족한 기업에 경우 솔루션 업체에 도움을 구해야 되는데, 문제는 솔루션 업체들도 현재 인력이 많이 없는 상황이예요. 그래서 쿠버네티스 전문 인력을 새로 뽑으려는 업체도 많고요.분명 기존 솔루션 엔지니어 분들은 회사에서 쿠버네티스를 공부하라는 압박이 있을 거에요. 이때 억지로 떠밀려서 공부하면 정말 재미가 없는데, 앞으로 또 10년 더 직장생활이라는 안정적인 먹거리를 위해서 지금 한번 고생을 해본다는 마음을 먹으시길 바라고, 몇년이 지난 후에는 이때의 선택을 잘했다고 생각하게 될 날이 분명히 올 겁니다. 쿠버네티스를 선택하면 따라오는 오픈소스들이 너무 많아요. 그리고 이 오픈소스들은 각각에 장단점이 있는데, 그 장단점이 대중적으로 정해졌다기 보단, 프로젝트 규모와 상황, 그리고 쓰는 사람들의 수준에 따라 다르거든요. 그래서 쿠버네티스 담당자는 제안서를 쓸 때부터 오픈을 할 때 까지 내가 이 오픈소스를 잘 선택한건지 계속 의문을 품게 되요.​정답은 없고, 이 프로젝트에서 이게 가장 효율적인 선택이었다라는 평가를 해줘야하는데, 그걸 최종적으로 해 주는 사람이 바로 PM/PL입니다. 새로운 기술에는 항상 반발이 있기 때문에 이분들이 기둥을 잘 잡아줘야 되요.​그래서 리더는 프로젝트를 하는 동안 담당자 얘기를 계속 경청하고 의견을 줘야겠지만, 최소한 누군가의 말에 휘둘리지 않는 정도의 지식은 있어야 겠죠? ​강의 특징먼저 이 강의를 위해서 네이버 카페(링크)를 만들었는데, 용도는 첫 번째로 강의 자료실 입니다. 앞에서 설명 드렸다시피 제 강의는 여러 Sprint로 나눠져서 만들 예정이라 이렇게 카페가 중심이 되서 저는 자료들을 통합적으로 관리 할거구요. 그러면 여러분들도 이 한곳에서 필요한 정보를 빠르게 캐치할 수 있게 되실 거예요.​두번째로, 여러분들의 복습 진도를 체크하려고 하는 건데 이 부분은 강의 중에 별도로 영상을 만들었으니까 수강 후에 보시기 바랍니다. 그리고 이 강의가 어떤 느낌의 강의인지는 강의 중간중간을 편집한 영상을 유튜브(링크)에 올려놨는데, 직접 보고 판단하시길 바랄게요. 제가 앞에서 어떤 강의를 만들어야겠다는 목표를 얘기를 했지만 영상 제작과 교육 기법에 대한 부분은 또 별개인 것 같아요. 그리고 저는 전문 강사는 아니기 때문에 그런 부분들은 직접 보시고 내가 수강하기에 편한 형태인지는 직접 판단을 해 보세요.​참고로 저는 이전에 만든 강의에서 들었던 단점을 보완하려고 노력을 했고, 인프런의 전체 강의의 별점이 1~2점인 수강평들을 쭉 보면서 나는 이런 실수는 하지 말아야지에 대해서 집중을 했습니다. 근데 제가 얼굴을 띄워 놓고 영상 강의를 하는 건 또 처음이라 표정이 좀 어색하더라도 이해를 부탁 드릴게요. 앞으로 점점 부드러워지지 않을까 싶어요 :) ​학습 내용[강의설명]에 이렇게 강의에 대한 주요 이미지들을 올려놨기 때문에 어떤 내용을 다루는 건지 알 수가 있어요! 만약 위 그림들로 부족하면 제가 강의를 만들면서 블로그(link)로 강의의 일부 내용을 올려놨습니다. 이 내용들을 보시고 충분히 판단을 한 다음에 강의를 수강 하세요. ​실습 환경​지상편 전체 실습 환경으로 개발 환경과 CI/CD 환경 그리고 인프라 환경을 구성할건데, 각 Sprint 마다 하나씩 구성이 될 예정이에요. 그래서 Sprint1 에서는 인프라 환경만 구성을 해서 실습이 진행된다고 보면 됩니다. ​최종적으로는 이 전체 환경을 직접 구성하고 활용할 수 있게 되는데, 이게 컨테이너 환경의 전체 파이프라인 입니다. [지상편]을 모두 잘 수강하면 이 내용들이 모두 내 PC위에서 돌아간다고 보시면 돼요. 이 흐름에 대한 내용은 강의 중에서 자세히 설명을 드릴께요.​​그래서 현재 Sprint1 에서는 이런 환경을 구성할 건데, 내 PC에 VirtualBox와 Vagrant를 이용해서 Guest OS를 띄우고 설치 스크립트로 인프라 환경을 쭉 만듭니다. 그리고 쿠버네티스를 다룰 때는 원격 접속 툴을 이용해서 서버에 들어가면 kubectl이라는 툴이 있고, 이걸로 쿠버네티스 명령을 날리면서 실습을 하고 브라우저로 대시보드에 접속을 해서 쿠버네티스를 조작하기도 해요. ​학습 자료는 인프런에 기본 수업자료를 다운받는 곳을 보면 PDF로 제공을 하고 있어요. ​그리고 수강평을 작성하신 분에 한에서 강의 자료실에서 원본 PPT를 받을 수 있으니까, 필요하신 분께서는 (링크)로 들어가서 방법을 읽어보세요. 그럼 여기까지 강의 소개를 마치며,이 강의가 여러분께 쿠버네티스를 쉽고 재미있게 시작하는데 도움이 됐으면 좋겠습니다.

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopscontainer강의소개

일프로

[kubernetes] 데브옵스 한방정리 #8

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 이번 블로그에서는 아래 DevOps를 구성하는 오픈소스들이라는 주제로 데브옵스를 설명을 드립니다. 내용의 수준은 비전공자가 데브옵스에 대한 전반적인 내용을 이해하기 좋은 정도인 점 참고 바래요.데브옵스를 구성하는 오픈소스들DevOps가 개발에서 운영까지 원할한 흐름을 만드는 건데, 중간에 가장 중요한 역할을 하는게 CI/CD죠. CI는 통합된 소스를 가지고 빌드/테스트를 자동화 시키는 기능을 만드는 거고, CD는 배포를 자동화 시키는 기능을 만드는 거예요.그래서 결국 개발을 해서 커밋을 하는 순간, 운영 환경에 App이 자동으로 배포가 되는 파이프라인이 만들어 지는데, 세부적으로 나누면 위 그림처럼 8가지 단계가 있습니다.계획/개발, 빌드/테스트, 릴리즈/배포, 그리고 운영/모니터링 인데, 이걸 각 단계를 대표적으로 사용하는 오픈소스를 가지고 얘기를 해보겠습니다.[계획] 단계부터 시작 할께요.제가 개발할 당시에는 redmine을 많이 쓰긴 했는데, 지금은 Jira나 notion을 많이 써요. 기능은 비슷한데, UI가 요즘 스타일로 많이 세련되 졌고요. 개발 일정을 공유하거나 이슈 사항들을 기록해야 되기 때문에 이런 툴을 사용하죠. 협업은 서로 메신저를 통해서 개발에 관련된 대화를 하는 걸 말하는데, 사실 카톡이나 사내 메신저를 써도 되는 부분이긴 하지만  그래도 슬렉을 쓰는 가장 큰 이유가 하나 있습니다. 그 이유는 가장 마지막에 설명 드릴께요. 다음으로 [개발]인데인텔리제이나, OpenJDK, 그리고 Spring Boot는 이전에 말씀 드렸고, 밑에 JUnit은 테스트 코드를 작성할 때 필요해요.보통 개발할때 if문 3~4개에 for문도 여러개 섞어서 복잡한 로직을 만들어 내죠. 이게 처음 만들 때는 집중해서 만들기 때문에 로직이 이해 되는데, 하루만 지나도 이 로직이 이해가 안되기 시작해요. 아무래 내가 짠 코드라도 다시 이해하는게 힘들어 지는데, 이럴때는 차라리 입력값을 넣어서 돌려보고, 결과값을 보는 게 로직을 이해하는 데 쉽거든요.그래서 바로 이런 테스트 코드를 만들어 놓는 게 좋고, 혹시라도 다른 사람이 이 로직을 수정하더라도, 테스트 코드를 돌려봐서 기대했던 값이 잘 나오면 안심을 할 수가 있죠. 그래서 코드를 개발할 때 조금만 고생해서 이렇게 테스트 코드도 같이 만들어 놓습니다. 다음으로 코드 분석 이라고 해서 FindBug나 PMD는 내가 짠 코드 패턴에 혹시 모를 버그가 있는지를 체크해줘요. 그래서 잘못된 로직을 짜지 않도록 도와주는데, 이런거 뿐만아니라 개발자간에 미리 코딩 스타일을 정해 놓거나, 개발 편의를 위해서 사용하는 툴 들은 엄청 많습니다. 다음으로 [빌드]를 볼께요.빌드 대상은 소스와 컨테이너고 Gradle과 도커가 사용됩니다. 소스 빌드로 현재 Maven보단 Gradle을 많이 쓰지만 저장소 자체는 메이븐 저장소에서 라이브러리를 가져 오는 거고요. 도커도 이전 [컨테이너 한방정리]에서 많이 얘기를 해서 이번엔 넘어 갈께요.  이제 다음으로 [테스트] 예요.테스트를 해야되는 요소에는 크게 3가지가 있는데, 기능이랑 성능 그리고 커버리지예요.각각 Junit, Jmeter, JACOCO라는 툴 들이 쓰이고. 각자 개발단계에서 테스트 코드를 만들고 실행을 해봤더라도 코드들이 병합되고 나서 또 다른 결과가 나올 수 있기 때문에, 빌드 단계에서 이 JUnit을 실행시켜서 자동으로 테스트를 한번 더 돌려 보는 거예요.그래서 위치는 이렇게 빌드에 연결되서 테스트가 같이 실행되는 거고, 테스트 이후에 Jacoco라는 툴을 돌리면 이 테스트를 돌렸을 때 사용된 로직들이, App 전체에서 어느정도 범위를 테스트 해본 건지, 커버리지를 결과를 알려줍니다.그래서 내가 돌려본 테스트 케이스들이 전체 로직에서 많은 부분을 차지할 수록, 이 App에 대한 신뢰도가 높다고 판단을 해요. 그리고 JMeter는 성능 테스트를 하는 툴 인데, 이건 자동화 기능은 아니고, 여기 개발환경이나 검증환경을 대상으로 진행 합니다. 통상 별도의 성능 테스트 전문 인력이 날잡아서 수동으로 진행하고요. 이제 다음으로 [릴리즈]와 [배포] 입니다.릴리즈는 배포 가능한 패키지를 만드는 과정이에요.도커 빌드를 하기 위해서는 Dockerfile이라는 스크립트를 작성해야 되고, 또 쿠버네티스에 배포를 하기 위해서 yaml 파일들을 사전에 만들어 놔야 되는데 이렇게 배포를 하기 위한 별도의 패키지를 만드는 게 릴리즈고, 이 파일들도 변경관리가 되야 하기 때문에 작성한 내용들을 이렇게 Github에 올려 놓습니다.그리고 배포할 때 사용을 하는데, 이 릴리즈와 이 배포 부분이 이번 Sprint2에서 다루게 될 주요 범위예요. 배포를 하기 위한 툴로는 대표적으로 kustomize와 helm 그리고 argoCD가 있고, 다 Sprint2 강의에서 배우게 됩니다. Sprint1 강의에서는 kubectl로 배포를 했지만, 이제 이런 도구들을 써서 쿠버네티스에 배포를 하게 되는 거죠. 이제 다음 단계로 [운영]입니다. 이건 실제 운영환경을 구성하는 요소와 툴 들이라고 보시면 되요. 여기서 Nginx와 Istio는 네트워크 트래픽 관리에 대한 도구고, 나머지 들은 [쿠버네티스 무겁게 설치하기]에서 나왔던 익숙한 그림일 거예요. 이외에도 운영을 구성하는 환경들은 다 표현하기 힘들 정도 많지만, 이정도로만 하고 이렇게 인프라 환경 안에서 설치되고, 운영자는 이 툴들이 정상적으로 잘 돌아가고 있는지 확인해야 하는 역할을 하죠.그리고 마지막으로 [모니터링]인데,모니터링 요소는 주로 자원 사용량이나 App로그 그리고 트래픽 흐름을 많이 봐요. Grafana 나 Loki 그리고 Prometheus는 Sprint1에서 사용을 해봤고. 이게 자원 사용량이랑 App로그를 보기 위한 툴이였죠?그리고 Jaeger랑 Zipkin은 트래픽 흐름을 보기 위한 도구예요. 이제 마이크로서비스 환경이 많아졌기 때문에 서비스들 간에 트래픽이 어떻게 흘러가는지 추적을 하는게 중요해 졌습니다. 그래서 이런 오픈소스들을 설치해야 되고위치는 운영과 똑같이 인프라 환경 내에 설치가 되요. 이 App들은 다 쿠버네티스 클러스터 위에서 Pod로 띄어 진다고 보시면 됩니다. 그럼 여기까지가 모니터링까지 다 설명을 드린거고,  아까 [Slack을 쓰는 이유]를 마지막에 말씀드린다고 했는데, 딴게 아니라 이렇게 연결되는 그림들이 있어야 되서 그래요. 이렇게 슬렉은 데브옵스에 중요 포인트 차지하고 있는 툴들이랑 연동이 할 수가 있거든요. 통상 메신저에는 개발자나, 데브옵스 엔지니어 혹은 운영자들이 모여 있는 방이 각각 있을 텐데, 슬렉을 쓰면 이 파이프라인에서 발생하는 알람들을 필요한 방에 울리도록 설정할 수가 있는거죠. 그래서 이게 협업을 위한 여러 메신저들 중에서, 그래도 슬렉을 쓰면 좋은 점 이었습니다. 자 그럼 여기까지가 데브옵스를 구성하는 오픈소스들에 대한 설명이였는데, 어떻게 데브옵스가 좀 실질적으로 와닿으시나요? 현재는 이렇게 데브옵스가 복잡해 졌습니다. 그래서 기업에서는 데브옵스 엔지니어를 별도로 뽑을 수 밖에 없는 거고요. 뭔가 많아 보이지만, 그래도 차근차근 하나씩 구성하다 보면 생각보다 금방 파이프라인이 만들어 지기도하고 여기 있는걸 한번에 다 만들 필요는 없어요. 배포를 한다고 처음부터 helm이나 argoCD를 적용할 필요는 없는 거고 Kubectl 배포부터 일단 연결을 해 놓은 다음에 하나씩 장비를 업그레이드 하는 마음으로 바꿔 나가면 되거든요.이번 강의도 그런 스탭으로 구성을 했으니까, 끝까지 잘 따라오시길 바라고요!아래 내용들은 강의에서 자세히 설명 드릴 내용들입니다. 쿠버네티스 어나더클래스 DevOps 전체 구성도 DevOps에서 가장 중요한 것 (개발->빌드->실행파일) DevOps에 엮인 IT 직군들 DevOps 외 다른 Ops들 ps. ♡ make me want to be a better man :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로kubernetes데브옵스devops오픈소스

일프로

[쿠어클#7-1] Application 기능으로 이해하기-Pod (probe)

 쿠버네티스를 공부 하다보면 경계를 해야 되는 상황이 있어요. 내가 어떤 개념을 힘들게 공부하고 사용법을 익혔을 때, 그 기능을 내가 하는 프로젝트에 적용 시키고 싶은 마음이 생기죠?여기까진 좋은데.그 기능을 적용함으로써 "운영에 불편한 관리 요소가 생기진 않을지?", "오히려 시스템에 복잡도만 증가 시키는 건 아닐지?" 는 충분히 고민하지 않는 경우가 있습니다.예를 들어, 쿠버네티스에는 NetworkPolicy 라는 object가 있는데, 쉽게 말해 Pod들 간에 방화벽 역할을 하는 는 기능 이예요. 보통 큰 프로젝트 환경을 보면 별도로 보안을  담당하는 사람이  있고, 내부 시스템을 외부에서 연결할 수 있도록 하거나 시스템 간에 통신을 해야 할 때 이 담당자한테 방화벽 오픈 신청을 먼저 하죠. 이렇게 전체적인 시스템에 대해서 방화벽이 관리되고 있는데, 쿠버네티스 클러스터 안에 NetworkPolicy를 적용하고 별도에 내부 방화벽 정책을 또 사용 할지에 대해서는 꼭 그렇게 해야 되는 이유를 충분히 고민 해봐야돼요.근데 오늘 배울 이 쿠버네티스의 기능은 백퍼센트 사용을 해야되지만 내 Application에 대한 충분한 이해가 없으면 생각지도 못한 장애를 만날 수가 있습니다.바로 Pod에 probe라는 기능인데요.실제로 저도 Pod가 내가 의도하지 않은 상황에서 죽었을 때, 원인을 분석하다 보면 이 기능을 잘못 사용해서 그랬던 적이 있을 만큼 정확하게 이해하고 적용 시켜야 되는 기술입니다. Pod (probe) - 프로브 기본 개념 3가지 종류가 있고 모두 /ready라는 url을 8080포트에 10초 간격으로 날리는데, 각각 성공이랑 실패에 대한 수치는 위 그림처럼 되어 있다고 해볼게요.컨테이너 안에 있는  App에서는 /ready라는 url이 사전에 만들어져 있어야 되고 Pod가 만들어지자마자 이 probe 기능들은 동작합니다.App은 처음 기동 중인 상태가 있고, 이때 쿠버네티스가 startupProbe 기능을 동작 시키면서  오브젝트 속성에 있는 대로 10초에 한 번씩 /ready라는 api를 App에 날려요. 기동 중일 때는 응답을 받을 수 없으니까 계속 실패가 될꺼고 10번 실패하기 전에 한번이라도 응답이 오면 성공으로 간주합니다. startupProbe 가 성공하면, 쿠버네티스는 startupProbe 기능을 중지 시키고 livenessProbe랑 readinessProbe기능을  동작 시킵니다. 그리고 또 설정 한대로 두 probe는 /ready라는 api를 10초 간격으로 반복해서 날리는데 App이 살아있는 동안에는 계속 200 OK 결과를 리턴 해주면서 이 두 probe 동작은 반복됩니다.각각의 역할은 다른데요.readinessProbe는 성공했을 때 외부 트래픽을  Pod가 받을 수 있는 상태로 만들어 주면서  서비스가 활성화 되고요. livenessProbe는 app이 살아 있는지를 계속 체크하는 역할 이예요. livenessProbe는 만약 App에 장애가 발생하게 되면, API는 실패를 하게 되고 설정에 따라 두 번을 실패하게 되면 쿠버네티스는 App을 재기동 시킵니다.이게 쿠버네티스에 프로브에 대한 기능이고, 일반적으로 자신에 App 기동 시간에 따라 startupProbe에 실패 횟수만 조정해서 쓰는 게 대부분인데 처음엔 이렇게 쓰더라도 어느 순간 이런 생각이 들 때가 있을 거예요. "왜 probe 마다 귀찮게  api들을 기입하는 항목이 각각 있을까?" 어차피 모두 같은 url을 지정해서 쓰는데, 그리고 또 한가지가 "어차피 장애가 나면 livenessProbe랑 readinessProbe는 같이 실패를 할 텐데, 굳이 readinessProbe도 계속 호출될 필요가 있을까?"쿠버네티스가 괜히 이렇게 해놓지는 않았을 텐데 "혹시 내가 이 프로브들을 제대로 쓰고 있는 게 아닌가?"이 프로브들을 간단하게만 써도 나쁘진 않지만 오늘은 이런 의문이 생기는 사람들을 위해서 probe에 대해서 좀 더 깊게 공부를 해보겠습니다. Pod (probe) - 실습카페 자료실 링크 (link)강의 영상에서는 실습이 함께 진행됩니다. Pod (probe) - 실습 로그 분석이제부터 실습 후 로그를 함께 분석해 볼게요. 먼저 App이 초기화 되기 시작했고, Spring이랑 Servlet을 초기화 과정이 있어요. 다음으로 Database를 연결하는데 실제 DB가 있는 건 아니고 그냥 제가 코드에 로그만 찍어 놓은거예요. 그리고 이렇게 App이 기동되는 동안 startupProbe는 계속 실패하고요. startupProbe가 찍히는 주기는 설정 해놓은대로 5초 간격이죠. 그리고 기동이 완료되면 startupProbe는 성공을 합니다. 근데 이 로그들은 startupProbe가 찍히는 걸 보여드리기 위해서 제가 임의로 코드를 구성했기 때문에 로그가 보이는 거예요. 무슨 말이냐면, 실제 App 상황에서는 쿠버네티스는 Pod가 생성되자마자 startupProbe를 작동 시키기 때문에 사실 처음부터 API는 실패 되고 있었거든요.이렇게 App이 기동 되기 전에는 API를 받지 못하기 때문에 실제로는 startupProbe에 로그가 찍힐 수가 없고, 만약에 Was로 tomcat을 썼다면 startupprobe가 찍히는 건 access.log 에서만 볼 수 있게 돼요.그래서 이 로그는 제가 임의로 코드를 구성한 학습적인 상황이라고 말씀드리는 거고요. 이제 기동이 완료가 됐고, [ConfigMap data is loading]은 사용자가 App이 기동 된 후에 외부에 데이터를 가져와서 추가적으로 시스템을 초기화 시키려는 상황 이예요. 그리고 밑에 livenessProbe랑 readinessProbe도 찍히기 시작했고요. 이때 readinessProbe는 실패했고, livenessProbe만 성공을 했네요. 그리고 추가적인 데이터 작업은 끝났고요.그림 제일 하단에 livenessProbe랑 readinessProbe는 계속 찍히고 있는데, 이제 둘 다 성공을 했네요. 그리고 호출 주기는 10초고요.근데 여기 보면 readinessProbe가 한번 실패를 했죠?이건 사용자 초기화 구간에는 readinessProbe가 실패 하도록 일부러 만든 거예요. 그래서 의도 한대로 현재 기능이 정확하게 동작을 해준 건데, 일단 이런 사실만 기억하고 다음으로 넘어가서 강의 영상에서 Application 동작 중심에 프로브를 다시한 번 설명 드립니다. 밑에 내용들을 강의 영상에서 설명 드릴 내용들 입니다. Pod (probe) - Application 동작 중심의 프로브 이해해당 내용은 근본적으로 쿠버네티스에서 왜 프로브라는 기능이 생겼는지 생각해봅니다.Pod (probe) - API 날려보며 프로브 동작 확인하기그리고 API를 날려보면서 앞에 설명한 기능들을 확인해보고요. Pod (probe) - 일시적 장애 상황에서의 프로브 활용마지막으로 일시적인 장애 상황에서 프로브를 좀 더 활용하는 방법을 얘기 해볼께요. 이렇게 강의를 모두 들으면 앞으로는 쿠버네티스에 프로브를 보게 될 때,내 app을 주의 깊게 관찰하게 되면서 어떻게 프로브를 잘 적용 시킬지 심각한 고민에 빠질 수 있게 되는 점 주의 바라며오늘 블로그는 여기까지 마치겠습니다. 해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다.강의 링크 : https://inf.run/NzKyps. 한번도 좋아요♡를 안 준 사람은 있어도, 한번만 좋아요♡를 준 사람은 없다. 당신은 어떤 사람인가요? :)

데브옵스 · 인프라인프런쿠버네티스어나더클래스지상편일프로kubernetesdevopskubeopsApplication기능으로이해하기Pod(probe)

일프로

[kubernetes] 손쉽게 데브옵스 환경을 구축하는 방법 #9

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 이번 강의에서 손쉽게 데브옵스 환경을 구축하는 방법으로 CI/CD 서버를 만들어 볼 건데, 먼저 간략하게 Sprint 2 범위에 실습 환경에 대해서 설명을 드릴께요.[지상편] 실습 환경 (전체범위)[지상편] 최종 실습환경 구성은 여기 보이는 환경들을 모두 설치하는 건데, 각 Sprint 마다 하나씩 환경을 구성해요. 이런 흐름이 내 PC에서 모두 이뤄지는 거고 Sprint1 때는 CI/CD환경이 없기 때문에 인프라 환경만 구성해서, 아래와 같이 실습을 해봤었죠?이제 Sprint2에서 CI/CD 환경을 구성 할 건데, Sprint2 환경 구성 범위먼저 인프라 환경때와 마찬가지로, Virtualbox랑 Vagrant를 이용하면, Guest OS가 만들어 지고, 스크립트를 통해서 이런 프로그램들이 모두 설치 됩니다. 뒤에서 설치 내용은 자세히 설명 드릴 거고요.설치가 다 완료 됐으면, 이제 내 PC에 브라우저에서 Jenkins dashboard를 접속을 할 수가 있게 되요. 그래서 빌드를 실행하면, 저에 Github에서 소스를 다운받아서 빌드가 실행 됩니다. 이 소스는 Sprint1에서 제가 실습을 위해서 만들었던 App에 소스고요.다음으로 컨테이너 빌드를 하면, 소스빌드를 해서 만들어진 Jar 파일이 사용되서 컨테이너 이미지가 만들어지고 Dockerhub로 업로드를 하게 되는데, 직접 도커허브에 가입해서, 내 도커 저장소에 이미지를 올릴 거예요. 그래서 지금까지 이렇게 제 도커 허브 username이 들어간 이미지를 사용했다면, 이제부터 자신이 가입한 username 으로 이미지 이름이 변경됩니다.그리고 도커빌드를 할때 필요한 도커파일이랑 배포를 할때 필요한 yaml 파일들을 저장할 용도로 Github가 필요한데, 기존에 있으신 분들은 그대로 쓰시면 되고요. 없으신 분들은 여기도 가입을 하셔야 되요. 그래서 컨테이너 빌드나 배포를 하면, 제 Github가 아닌, 본인에 Github에서 릴리즈 파일들을 다운 받아서 배포를 하게 되는데여기서 중요한건, 이 배포되는 yaml 파일에 들어가는 image 명에 내 도커허브 username이 있어야 여기서 이미지를 가져 올수 있어요. 이게 이번 Sprint2에 실습 구성과 진행 흐름인데 만약에 좀 헷갈려도 걱정하지 마세요. 한번 더 설명 드릴 꺼에요.단계별 설치 시작먼저 Sprint1에서 했던 것 처럼, 제가 올려놓은 Vagrant 설치 스크립트를 실행하면, 이렇게 CI/CD  서버가 한번에 구성되는데, 이 설치 스크립트에서 일어나는 일을 설명 드릴께요.Vagrantfile로 설치되는 내용먼저, 자원 할당을 보면, CPU 2 core에 Memory 2Gi, Disk 30기가를 줬어요. 그리고 Sprint2 부터는 실습할 때 이 두 환경이 모두 띄어져 있어야 되니까. 내 pc에 자원이 충분한지 확인을 해보시고요.그리고 네트워크 설정을 보시면, IP는 인프라 환경이 30번이었고, CI/CD 서버는 20번 이예요. Host-Only Network는  VM간에 통신을 하거나 내 호스트 PC에서 VM을 접속하기 위한 네트워크라서 IP가 같으면 안되고 근데 이 네트워크는 외부 인터넷에 접속은 안되거든요.그래서 NAT를 추가로 쓰는거고, IP는 자동할당  되는데, 이 IP가 인프라 환경이랑 같지만 인터넷만 쓰기 위한 용도라 문제는 안됩니다.다음으로 여기서 부터가 본격적으로 설치 스크립트에 해당하는 부분인데, 첫번째로 리눅스 기본 설정에 대한 내용들이고 이건 인프라 환경에 쿠버네티스를 설치할 때도 했던 내용이예요.그리고 kubectl을 설치 합니다. 이건 젠킨스에서 배포할때 쓸 용도고여 NAT를 설정해놨기 때문에 이렇게 외부 저장소에서 이 kubectl 패키지를 다운 받아서 설치할 수 있는 거죠. 그리고 마찬가지로 Docker 설치가 있어요. 이걸로 젠킨스에서 컨테이너 빌드를 하고, dockerhub로 이미지를 올리게 되고 다음으로 소스 빌드를 해야되니까 OpenJdk랑 Gradle 설치가 있습니다.그리고 Git도 설치를 해서, 빌드에 쓸 소스 코드랑  릴리즈 파일들을 가져와요.마지막으로 Jenkins를 설치하는데, 이때 OpenJDK를 11 버전으로 하나더 설치해요. 그 이유는 젠킨스가 11버전에 돌아가기 때문에 Jenkins 설치용으로 필요한거고 이건 제가 만든 소스코드가 17버전으로 만들었기 때문에 소스코드 빌드용으로 필요한 거에요. 다시 여길로 돌아와서, 이렇게 Vagrant로 CI/CD 서버가 만들어 졌으면 원격접속 툴로 접속을 해놓고요.그리고 이제 Jenkins 대시보드에도 접속해볼 수 있는데, 여기에 접속하면 최초 젠킨스 초기 세팅을 한번 하게되요. 사용자 생성하고 권장 플러그인들을 다운받는 그런 과정들이 있고 다음으로 전역 설정이라는 걸 하는데, 이게 뭐냐면 이 직접 설치한 버전에 Gradle이랑 OpenJdk를 젠킨스에서 빌드를 할 때 사용하겠다고 등록 하는거예요. 그리고 다음으로 이제 자신에 dockerhub를 써야 되니까 도커허브에 가입하는 단계가 있고요.다음으로 dockerhub 사용 설정이라고 해서, 두 가지가 있는데 첫 번째는 내 CI/CD 서버에서 내 도커허브로 이미지를 올릴 수 있도록 로그인을 해 놓는 거랑 두 번째로 젠킨스에서 docker를 사용할 수 있도록 권한을 부여 해야 합니다.그리고 다음으로 인프라 환경에 있는 인증서를 이 CI/CD 환경에 복사 해줘야 돼요. 그래야 젠킨스에서 kubectl로 배포를 할 때 쿠버네티스에 API를 날릴 수 있습니다.그리고 다음으로 내 Github에 가입을 하고, 설정이 있는데, 설정이 뭐냐면, 제 Github에 Dockerfile이랑 yaml파일들이 있거든요. 이걸 본인이 가입한 Github로 복사해 가는거예요. 그리고 복사하면, Deployment 파일 image 부분에 제 Dockerhub username이 있을 텐데, 이 부분을 수정하는 내용이 있고.마지막으로 젠킨스에서 빌드/배포를 하기위한 프로젝트 설정이 있습니다. 실행버튼을 누르게 되면 쿠버네티스에서 리소스가 생성되고요. 그중에서 Pod를 만들 때 이미지는 이젠 내 도커허브에서 가져가는 거죠.그래서 이렇게가 전체적인 설치 순서고, 이제 두번 정도 설명드릴 셈인데, 어떻게 이해가 잘 되셔나요?뭔가 많아 보일 수는 있는데, 제가 까페에 올려놓는 설치 가이드를 따라하다보면 정말 금방이고 근데 이것도 CI/CD가 흘러가기 위한 최소한에 기능만 쓴거에요. 이 흐름을 시작으로 배포강의가 진행되면서 점점 더 고도화가 됩니다.아래 자세한 설치 가이드가 있는 링크를 걸어 놓을께요.https://cafe.naver.com/kubeops/84만약, 해당 내용으로 설치가 힘드시다면 제 강의에서 설치 실습 영상을 추천 드립니다 :) ps. ♡ make me want to be a better man :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로kubernetes데브옵스인프런devopsjenkins

이상현

[인프런 워밍업 클럽 4기] DevOps 발자국 3주차

[ 강의 정보 ]강의명 : 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2 [ 워밍업 클럽 3주차 회고 ]3주차쯔음 들어가니 슬슬 밀린 복습들이 생겨나고 있다.. 평일에 부지런히 하면 좋았을련만 주말에 2주차에 밀린 것까지 하려니 시간이 너무 없다 @.@ 평일에 저녁약속이다 뭐다 여러 가지일로 미뤄온 결과라고 생각하며 열심히 달려본다 흑흑 이번 주차에서는 CI/CD 구축과 함께 Recreate, RollingUpdate, Blue/Green, Canary 와 같이 더 다양한 배포전략을 알아보았다. Jenkins를 설치하는 과정에서 아래의 약간의 에러(?)가 있었는데 Gemini의 힘을 빌려 생각보다 빠르게 해결할 수 있었다. 맞닥뜨린 에러와 해결방법은 블로그에 짧게 기재두었다. 바로가기 👉👉https://velog.io/@zxd985/인프런-워밍업-클럽-4기-DevOps-3주차-2처음에는 인터넷 서치로 찾아보려 했으나.. 키워드를 잘 설정하지 못한 것인지 잘 안나와서 결국 AI의 힘을 빌렸다ㅎ..이전에는 이미 설치되어 있는 Jenkins 서버에서 빌드 버튼만 딸깍. 했었는데 직접 설치부터 Item 생성 > Build Step 구성까지 모두 직접해보니 어떻게 Jenkins CI/CD가 동작하는 것인지 흐름을 이해할 수 있었다. 배포 전략 중에서는 Canary 배포가 현업에 매우 필요하다고 느꼈는데 한번에 트래픽을 넘기는 것이 아닌, 일정 비율의 트래픽만 전환하면서 에러의 여부를 확인하는 것이 서비스를 이용하는 고객에게 오류를 덜 노출할 수 있고 빠르게 롤백할 수 있을 것 같다고 생각했기 때문이다. 또한, A/B 테스트 등 헤더를 활용해 특정 고객에게만 신규 버전을 노출하는 등 여러 비즈니스를 테스트하기에 적합할 것 같다. 다만 istio와 같은 서비스 메시도 알아야 한다는 크나큰 산이 ....이래 저래 정신없이 3주차가 지나가고 있는데, 과연 내가 스터디를 잘하고 있나 라는 의구심도 들면서도... 그래도 마지막까지 잘 달려보고 싶다는 생각이 든다. 조금만 더 화이팅 해보자! 인프런 워밍업 클럽 4기 블로그 시리즈

kubernetesdevops

David

[인프런 워밍업 클럽 4기 - DevOps] 미션 5

사전 준비사항# 도커 파일 및 App 소스 다운로드 curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/Dockerfile curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/hello.js [root@cicd-server ~]# ls Dockerfile hello.js전체 실습 명령어docker build -t golreas/hello:1.0.0 .[+] Building 12.1s (8/8) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 154B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/node:slim 2.3s => [auth] library/node:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.0s => => transferring context: 272B 0.0s => [1/2] FROM docker.io/library/node:slim@sha256:b30c143a092c7dced8e17ad67a8783c03234d4844ee84c39090c9780491aaf89 9.5s => => resolve docker.io/library/node:slim@sha256:b30c143a092c7dced8e17ad67a8783c03234d4844ee84c39090c9780491aaf89 0.0s => => sha256:85878ac12a824d35ede83635c5aa0a6b4c83fe0b8fa5fb125e1fc839a5af01a7 6.59kB / 6.59kB 0.0s => => sha256:34ef2a75627f6089e01995bfd3b3786509bbdc7cfb4dbc804b642e195340dbc9 28.08MB / 28.08MB 7.8s => => sha256:00b6bc59183634774862a1f5d9fa777966ffdd8b4edd6fe07006671358dfc249 3.31kB / 3.31kB 0.5s => => sha256:7293ae927b976710c33b54ae3957471f36b9e1150408853c3dfbd7baff3f59d1 50.52MB / 50.52MB 7.6s => => sha256:b30c143a092c7dced8e17ad67a8783c03234d4844ee84c39090c9780491aaf89 5.20kB / 5.20kB 0.0s => => sha256:af442a7998c3f3a985309cfa7b709ea8d3f1911ea19a598f1f1a2e158273c73e 1.93kB / 1.93kB 0.0s => => sha256:148b7926ba2143f7dbd1efaab45bd08b5fde13f01510d1319ee7cd0aa781f8d0 1.71MB / 1.71MB 1.9s => => sha256:0a5428d7ed1bdde6d0638d39b519fcd3307eb60e70ba9f220d1066b39a71de93 447B / 447B 2.1s => => extracting sha256:34ef2a75627f6089e01995bfd3b3786509bbdc7cfb4dbc804b642e195340dbc9 0.6s => => extracting sha256:00b6bc59183634774862a1f5d9fa777966ffdd8b4edd6fe07006671358dfc249 0.0s => => extracting sha256:7293ae927b976710c33b54ae3957471f36b9e1150408853c3dfbd7baff3f59d1 0.7s => => extracting sha256:148b7926ba2143f7dbd1efaab45bd08b5fde13f01510d1319ee7cd0aa781f8d0 0.1s => => extracting sha256:0a5428d7ed1bdde6d0638d39b519fcd3307eb60e70ba9f220d1066b39a71de93 0.0s => [2/2] COPY hello.js . 0.2s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:f8812cc66e7be6bd8a78ca25a7701407a6aa40bf06d11ca572f61d63c91944a6 0.0s => => naming to docker.io/golreas/hello:1.0.0$ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 1.0.0 f8812cc66e7b 48 seconds ago 249MB golreas/api-tester v1.0.0 9438a37e6182 3 hours ago 520MB# docker login -u golreas Password: WARNING! Your password will be stored unencrypted in /var/lib/jenkins/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [jenkins@cicd-server ~]$ docker push golreas/hello:1.0.0 The push refers to repository [docker.io/golreas/hello] 84cd54ae51c5: Pushed a04dc377afe1: Mounted from library/node 1b2a793e9797: Mounted from library/node 0fa9dab4f369: Mounted from library/node abb3903f11f9: Mounted from library/node 6edfb9bfff29: Mounted from library/node 1.0.0: digest: sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 size: 1574 docker rmi golreas/hello:1.0.0 Untagged: golreas/hello:1.0.0 [jenkins@cicd-server ~] docker pull golreas/hello:1.0.0 1.0.0: Pulling from golreas/hello Digest: sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 Status: Downloaded newer image for golreas/hello:1.0.0 docker.io/golreas/hello:1.0.0 docker save -o file.tar golreas/hello:1.0.0 [jenkins@cicd-server ~]$ docker load -i file.tar Loaded image: golreas/hello:1.0.0 빌드$ docker build -t golreas/hello:1.0.0 . [+] Building 1.7s (8/8) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 154B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/node:slim 1.7s => [auth] library/node:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.0s => => transferring context: 87B 0.0s => [1/2] FROM docker.io/library/node:slim@sha256:b30c143a092c7dced8e17ad67a8783c03234d4844ee84c39090c9780491aaf89 0.0s => CACHED [2/2] COPY hello.js . 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:f8812cc66e7be6bd8a78ca25a7701407a6aa40bf06d11ca572f61d63c91944a6 0.0s => => naming to docker.io/golreas/hello:1.0.0이미지 리스트 조회$ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 1.0.0 f8812cc66e7b 10 minutes ago 249MB golreas/api-tester v1.0.0 9438a37e6182 3 hours ago 520MB태그변경docker tag golreas/hello:1.0.0 golreas/hello:2.0.0 $ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 1.0.0 f8812cc66e7b 13 minutes ago 249MB golreas/hello 2.0.0 f8812cc66e7b 13 minutes ago 249MB golreas/api-tester v1.0.0 9438a37e6182 4 hours ago 520MB로그인docker login -u golreas Password: WARNING! Your password will be stored unencrypted in /var/lib/jenkins/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded이미지 업로드docker push golreas/hello:1.0.0 The push refers to repository [docker.io/golreas/hello] 84cd54ae51c5: Layer already exists a04dc377afe1: Layer already exists 1b2a793e9797: Layer already exists 0fa9dab4f369: Layer already exists abb3903f11f9: Layer already exists 6edfb9bfff29: Layer already exists 1.0.0: digest: sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 size: 1574이미지 다운로드docker pull golreas/hello:1.0.0 1.0.0: Pulling from golreas/hello Digest: sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 Status: Image is up to date for golreas/hello:1.0.0 docker.io/golreas/hello:1.0.0이미지 -> 파일로 변환docker save -o file.tar golreas/hello:1.0.0 [jenkins@cicd-server ~]$ ls -l file.tar -rw-------. 1 jenkins jenkins 255018496 Jun 15 00:37 file.tar이미지 삭제docker rmi golreas/hello:1.0.0 Untagged: golreas/hello:1.0.0파일 -> 이미지로 변환docker load -i file.tar Loaded image: golreas/hello:1.0.0 [jenkins@cicd-server ~]$ docker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 1.0.0 f8812cc66e7b 19 minutes ago 249MB golreas/hello 2.0.0 f8812cc66e7b 19 minutes ago 249MB golreas/api-tester v1.0.0 9438a37e6182 4 hours ago 520MB정리docker rmi golreas/hello:1.0.0 Untagged: golreas/hello:1.0.0 [jenkins@cicd-server ~]$ rm file.tar Containerdctr ns list NAME LABELS k8s.io특정 네임스페이스 내 이미지 조회ctr -n k8s.io image list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/1pro/api-tester:v1.0.0 application/vnd.oci.image.index.v1+json sha256:6b38dd347b66c7f14c393280a040831a72b4a93fd5beddc011ee852c26f35058 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/api-tester:v2.0.0 application/vnd.oci.image.index.v1+json sha256:eed09de27648c5e13a7978069e1af63908bf4c6fd023d73de993e8b6abf556b4 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/api-tester@sha256:6b38dd347b66c7f14c393280a040831a72b4a93fd5beddc011ee852c26f35058 application/vnd.oci.image.index.v1+json sha256:6b38dd347b66c7f14c393280a040831a72b4a93fd5beddc011ee852c26f35058 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/api-tester@sha256:eed09de27648c5e13a7978069e1af63908bf4c6fd023d73de993e8b6abf556b4 application/vnd.oci.image.index.v1+json sha256:eed09de27648c5e13a7978069e1af63908bf4c6fd023d73de993e8b6abf556b4 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app-error:latest application/vnd.oci.image.index.v1+json sha256:cb23f9634d689a4fd2c34c2132f26ddc2361f15bc6320f9682304e3503ca0056 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app-error@sha256:cb23f9634d689a4fd2c34c2132f26ddc2361f15bc6320f9682304e3503ca0056 application/vnd.oci.image.index.v1+json sha256:cb23f9634d689a4fd2c34c2132f26ddc2361f15bc6320f9682304e3503ca0056 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app-update:latest application/vnd.oci.image.index.v1+json sha256:37b78640822e2563ecab155f691a2eef977472745ea09f6013e0e7f5402d64a9 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app-update@sha256:37b78640822e2563ecab155f691a2eef977472745ea09f6013e0e7f5402d64a9 application/vnd.oci.image.index.v1+json sha256:37b78640822e2563ecab155f691a2eef977472745ea09f6013e0e7f5402d64a9 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app:latest application/vnd.oci.image.index.v1+json sha256:9d81d340d25b6bf7ec48e742cc149c170cdf8c94263da540a7d7034be476bd6b 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/1pro/app@sha256:9d81d340d25b6bf7ec48e742cc149c170cdf8c94263da540a7d7034be476bd6b application/vnd.oci.image.index.v1+json sha256:9d81d340d25b6bf7ec48e742cc149c170cdf8c94263da540a7d7034be476bd6b 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed docker.io/calico/apiserver:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:c520f71091cd09a9c9628a4e010f6fbc6118da9573af46af5b3f4c3ed8d463dc 34.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/apiserver@sha256:c520f71091cd09a9c9628a4e010f6fbc6118da9573af46af5b3f4c3ed8d463dc application/vnd.docker.distribution.manifest.list.v2+json sha256:c520f71091cd09a9c9628a4e010f6fbc6118da9573af46af5b3f4c3ed8d463dc 34.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/cni:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:7c5895c5d6ed3266bcd405fbcdbb078ca484688673c3479f0f18bf072d58c242 82.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/cni@sha256:7c5895c5d6ed3266bcd405fbcdbb078ca484688673c3479f0f18bf072d58c242 application/vnd.docker.distribution.manifest.list.v2+json sha256:7c5895c5d6ed3266bcd405fbcdbb078ca484688673c3479f0f18bf072d58c242 82.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/csi:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:0ab0fafee845c82c1a31bc2a3d5df29768626d570fbbead4813ad0da4a4ebf4b 9.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/csi@sha256:0ab0fafee845c82c1a31bc2a3d5df29768626d570fbbead4813ad0da4a4ebf4b application/vnd.docker.distribution.manifest.list.v2+json sha256:0ab0fafee845c82c1a31bc2a3d5df29768626d570fbbead4813ad0da4a4ebf4b 9.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/kube-controllers:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:5fce14b4dfcd63f1a4663176be4f236600b410cd896d054f56291c566292c86e 28.0 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/kube-controllers@sha256:5fce14b4dfcd63f1a4663176be4f236600b410cd896d054f56291c566292c86e application/vnd.docker.distribution.manifest.list.v2+json sha256:5fce14b4dfcd63f1a4663176be4f236600b410cd896d054f56291c566292c86e 28.0 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/node-driver-registrar:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:77db9df0ecd41c514d8dcab3b2681091f98f8d70e29a03df12c086a4e032639b 11.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/node-driver-registrar@sha256:77db9df0ecd41c514d8dcab3b2681091f98f8d70e29a03df12c086a4e032639b application/vnd.docker.distribution.manifest.list.v2+json sha256:77db9df0ecd41c514d8dcab3b2681091f98f8d70e29a03df12c086a4e032639b 11.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/node:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:a8b77a5f27b167501465f7f5fb7601c44af4df8dccd1c7201363bbb301d1fe40 83.6 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/node@sha256:a8b77a5f27b167501465f7f5fb7601c44af4df8dccd1c7201363bbb301d1fe40 application/vnd.docker.distribution.manifest.list.v2+json sha256:a8b77a5f27b167501465f7f5fb7601c44af4df8dccd1c7201363bbb301d1fe40 83.6 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/pod2daemon-flexvol:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:cf169a0c328a5b4f2dc96b224c3cf6dbc2c8269c6ecafac54bc1de00102b665e 5.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/pod2daemon-flexvol@sha256:cf169a0c328a5b4f2dc96b224c3cf6dbc2c8269c6ecafac54bc1de00102b665e application/vnd.docker.distribution.manifest.list.v2+json sha256:cf169a0c328a5b4f2dc96b224c3cf6dbc2c8269c6ecafac54bc1de00102b665e 5.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/typha:v3.26.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:ebe99272d38ff65255c1fba33c17d10f588b612625b19c68fe5aeed0f134fa74 24.7 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/calico/typha@sha256:ebe99272d38ff65255c1fba33c17d10f588b612625b19c68fe5aeed0f134fa74 application/vnd.docker.distribution.manifest.list.v2+json sha256:ebe99272d38ff65255c1fba33c17d10f588b612625b19c68fe5aeed0f134fa74 24.7 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/grafana/grafana:9.5.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:39c849cebccccb22c0a5194f07c535669386190e029aa440ad535226974a5809 78.2 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/grafana/grafana@sha256:39c849cebccccb22c0a5194f07c535669386190e029aa440ad535226974a5809 application/vnd.docker.distribution.manifest.list.v2+json sha256:39c849cebccccb22c0a5194f07c535669386190e029aa440ad535226974a5809 78.2 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/grafana/loki:2.6.1 application/vnd.docker.distribution.manifest.list.v2+json sha256:1ee60f980950b00e505bd564b40f720132a0653b110e993043bb5940673d060a 17.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/grafana/loki@sha256:1ee60f980950b00e505bd564b40f720132a0653b110e993043bb5940673d060a application/vnd.docker.distribution.manifest.list.v2+json sha256:1ee60f980950b00e505bd564b40f720132a0653b110e993043bb5940673d060a 17.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/grafana/promtail:2.7.4 application/vnd.docker.distribution.manifest.list.v2+json sha256:db66221bcc9510f3101121d42354b19c83cb810c5480e4936eb75c43443656f4 65.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/grafana/promtail@sha256:db66221bcc9510f3101121d42354b19c83cb810c5480e4936eb75c43443656f4 application/vnd.docker.distribution.manifest.list.v2+json sha256:db66221bcc9510f3101121d42354b19c83cb810c5480e4936eb75c43443656f4 65.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed docker.io/kubernetesui/dashboard:v2.7.0 application/vnd.docker.distribution.manifest.list.v2+json sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93 70.7 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/kubernetesui/dashboard@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93 application/vnd.docker.distribution.manifest.list.v2+json sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93 70.7 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/kubernetesui/metrics-scraper:v1.0.8 application/vnd.docker.distribution.manifest.list.v2+json sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c 17.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed docker.io/kubernetesui/metrics-scraper@sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c application/vnd.docker.distribution.manifest.list.v2+json sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c 17.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/brancz/kube-rbac-proxy:v0.14.1 application/vnd.docker.distribution.manifest.list.v2+json sha256:58d91a5faaf8f8222f8aa6c0a170826bbabcc60eedab71afd2326548cde84171 21.9 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/brancz/kube-rbac-proxy@sha256:58d91a5faaf8f8222f8aa6c0a170826bbabcc60eedab71afd2326548cde84171 application/vnd.docker.distribution.manifest.list.v2+json sha256:58d91a5faaf8f8222f8aa6c0a170826bbabcc60eedab71afd2326548cde84171 21.9 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus-operator/prometheus-config-reloader:v0.65.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:18632ea5cff38cda5b08054057297e527dcfc144a5f195c1c836a0805a9bbad1 4.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus-operator/prometheus-config-reloader@sha256:18632ea5cff38cda5b08054057297e527dcfc144a5f195c1c836a0805a9bbad1 application/vnd.docker.distribution.manifest.list.v2+json sha256:18632ea5cff38cda5b08054057297e527dcfc144a5f195c1c836a0805a9bbad1 4.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus-operator/prometheus-operator:v0.65.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:5c3da991d54f5ff9b84e5a1fb55110b4de7fcd00723367eff6f90392ad01e79b 14.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus-operator/prometheus-operator@sha256:5c3da991d54f5ff9b84e5a1fb55110b4de7fcd00723367eff6f90392ad01e79b application/vnd.docker.distribution.manifest.list.v2+json sha256:5c3da991d54f5ff9b84e5a1fb55110b4de7fcd00723367eff6f90392ad01e79b 14.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus/node-exporter:v1.6.0 application/vnd.docker.distribution.manifest.list.v2+json sha256:d2e48098c364e61ee62d9016eed863b66331d87cf67146f2068b70ed9d9b4f98 10.5 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus/node-exporter@sha256:d2e48098c364e61ee62d9016eed863b66331d87cf67146f2068b70ed9d9b4f98 application/vnd.docker.distribution.manifest.list.v2+json sha256:d2e48098c364e61ee62d9016eed863b66331d87cf67146f2068b70ed9d9b4f98 10.5 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus/prometheus:v2.44.0 application/vnd.docker.distribution.manifest.list.v2+json sha256:0f0b7feb6f02620df7d493ad7437b6ee95b6d16d8d18799f3607124e501444b1 83.4 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/prometheus/prometheus@sha256:0f0b7feb6f02620df7d493ad7437b6ee95b6d16d8d18799f3607124e501444b1 application/vnd.docker.distribution.manifest.list.v2+json sha256:0f0b7feb6f02620df7d493ad7437b6ee95b6d16d8d18799f3607124e501444b1 83.4 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/tigera/operator:v1.30.9 application/vnd.docker.distribution.manifest.list.v2+json sha256:431f037ff18b5c867d01312e42671effc55602421aeed25dd3f6109f70596b4a 18.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed quay.io/tigera/operator@sha256:431f037ff18b5c867d01312e42671effc55602421aeed25dd3f6109f70596b4a application/vnd.docker.distribution.manifest.list.v2+json sha256:431f037ff18b5c867d01312e42671effc55602421aeed25dd3f6109f70596b4a 18.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/coredns/coredns:v1.10.1 application/vnd.docker.distribution.manifest.list.v2+json sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e 13.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/mips64le,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/coredns/coredns@sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e application/vnd.docker.distribution.manifest.list.v2+json sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e 13.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/mips64le,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/etcd:3.5.7-0 application/vnd.docker.distribution.manifest.list.v2+json sha256:51eae8381dcb1078289fa7b4f3df2630cdc18d09fb56f8e56b41c40e191d6c83 76.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/etcd@sha256:51eae8381dcb1078289fa7b4f3df2630cdc18d09fb56f8e56b41c40e191d6c83 application/vnd.docker.distribution.manifest.list.v2+json sha256:51eae8381dcb1078289fa7b4f3df2630cdc18d09fb56f8e56b41c40e191d6c83 76.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/kube-apiserver:v1.27.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:94e48585629fde3c1d06c6ae8f62885d3052f12a1072ffd97611296525eff5b9 29.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-apiserver@sha256:94e48585629fde3c1d06c6ae8f62885d3052f12a1072ffd97611296525eff5b9 application/vnd.docker.distribution.manifest.list.v2+json sha256:94e48585629fde3c1d06c6ae8f62885d3052f12a1072ffd97611296525eff5b9 29.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-controller-manager:v1.27.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:b0990ef7c9ce9edd0f57355a7e4cb43a71e864bfd2cd55bc68e4998e00213b56 26.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-controller-manager@sha256:b0990ef7c9ce9edd0f57355a7e4cb43a71e864bfd2cd55bc68e4998e00213b56 application/vnd.docker.distribution.manifest.list.v2+json sha256:b0990ef7c9ce9edd0f57355a7e4cb43a71e864bfd2cd55bc68e4998e00213b56 26.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-proxy:v1.27.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:1e4f13f5f5c215813fb9c9c6f56da1c0354363f2a69bd12732658f79d585864f 20.4 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-proxy@sha256:1e4f13f5f5c215813fb9c9c6f56da1c0354363f2a69bd12732658f79d585864f application/vnd.docker.distribution.manifest.list.v2+json sha256:1e4f13f5f5c215813fb9c9c6f56da1c0354363f2a69bd12732658f79d585864f 20.4 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-scheduler:v1.27.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:89e8c591cc58bd0e8651dddee3de290399b1ae5ad14779afe84779083fe05177 15.8 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-scheduler@sha256:89e8c591cc58bd0e8651dddee3de290399b1ae5ad14779afe84779083fe05177 application/vnd.docker.distribution.manifest.list.v2+json sha256:89e8c591cc58bd0e8651dddee3de290399b1ae5ad14779afe84779083fe05177 15.8 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.9.2 application/vnd.docker.distribution.manifest.list.v2+json sha256:5ac2e67a862cd3baa0eb4fd7683d54928fd76ea3a61cde50508922c956901d8c 11.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/kube-state-metrics/kube-state-metrics@sha256:5ac2e67a862cd3baa0eb4fd7683d54928fd76ea3a61cde50508922c956901d8c application/vnd.docker.distribution.manifest.list.v2+json sha256:5ac2e67a862cd3baa0eb4fd7683d54928fd76ea3a61cde50508922c956901d8c 11.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/metrics-server/metrics-server:v0.6.3 application/vnd.docker.distribution.manifest.list.v2+json sha256:c60778fa1c44d0c5a0c4530ebe83f9243ee6fc02f4c3dc59226c201931350b10 26.7 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/metrics-server/metrics-server@sha256:c60778fa1c44d0c5a0c4530ebe83f9243ee6fc02f4c3dc59226c201931350b10 application/vnd.docker.distribution.manifest.list.v2+json sha256:c60778fa1c44d0c5a0c4530ebe83f9243ee6fc02f4c3dc59226c201931350b10 26.7 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/pause:3.6 application/vnd.docker.distribution.manifest.list.v2+json sha256:3d380ca8864549e74af4b29c10f9cb0956236dfb01c40ca076fb6c37253234db 247.6 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/pause:3.9 application/vnd.docker.distribution.manifest.list.v2+json sha256:7031c1b283388d2c2e09b57badb803c05ebed362dc88d84b480cc47f72a21097 261.8 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/pause@sha256:3d380ca8864549e74af4b29c10f9cb0956236dfb01c40ca076fb6c37253234db application/vnd.docker.distribution.manifest.list.v2+json sha256:3d380ca8864549e74af4b29c10f9cb0956236dfb01c40ca076fb6c37253234db 247.6 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/pause@sha256:7031c1b283388d2c2e09b57badb803c05ebed362dc88d84b480cc47f72a21097 application/vnd.docker.distribution.manifest.list.v2+json sha256:7031c1b283388d2c2e09b57badb803c05ebed362dc88d84b480cc47f72a21097 261.8 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.10.0 application/vnd.docker.distribution.manifest.list.v2+json sha256:2f34cb3a04a0fee6034f4d63ce3ee7786c0f762dc9f3bf196c70e894dd92edd1 26.4 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed registry.k8s.io/prometheus-adapter/prometheus-adapter@sha256:2f34cb3a04a0fee6034f4d63ce3ee7786c0f762dc9f3bf196c70e894dd92edd1 application/vnd.docker.distribution.manifest.list.v2+json sha256:2f34cb3a04a0fee6034f4d63ce3ee7786c0f762dc9f3bf196c70e894dd92edd1 26.4 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:031fce34fb773858da957c7d5d550cdd5050d11a61b81ce637f5c8e757cd9569 application/vnd.docker.distribution.manifest.list.v2+json sha256:77db9df0ecd41c514d8dcab3b2681091f98f8d70e29a03df12c086a4e032639b 11.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:20b332c9a70d8516d849d1ac23eff5800cbb2f263d379f0ec11ee908db6b25a8 application/vnd.docker.distribution.manifest.list.v2+json sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93 70.7 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:24bc64e911039ecf00e263be2161797c758b7d82403ca5516ab64047a477f737 application/vnd.docker.distribution.manifest.list.v2+json sha256:51eae8381dcb1078289fa7b4f3df2630cdc18d09fb56f8e56b41c40e191d6c83 76.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed sha256:29921a084542255eb81a1a660a603b1a24636d88b202f9010daae75fa32754c0 application/vnd.docker.distribution.manifest.list.v2+json sha256:1e4f13f5f5c215813fb9c9c6f56da1c0354363f2a69bd12732658f79d585864f 20.4 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:2d68052f05879837d499699bebc3039f71b65c486fce80da7b120e134ba3181c application/vnd.docker.distribution.manifest.list.v2+json sha256:1ee60f980950b00e505bd564b40f720132a0653b110e993043bb5940673d060a 17.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed sha256:2e8b6dfeda0f17c6856f93d62f115266ce424ec2ddc8c6e5c06af3664d8e66a9 application/vnd.docker.distribution.manifest.list.v2+json sha256:5fce14b4dfcd63f1a4663176be4f236600b410cd896d054f56291c566292c86e 28.0 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:2ee705380c3c59a538b853cbe9ae9886ebbd0001a4cea4add5adeea48e5f48d4 application/vnd.docker.distribution.manifest.list.v2+json sha256:b0990ef7c9ce9edd0f57355a7e4cb43a71e864bfd2cd55bc68e4998e00213b56 26.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:305d7ed1dae2877c3a80d434c5fb9f1aac1aa3d2431c36130a3fcd1970e93840 application/vnd.docker.distribution.manifest.list.v2+json sha256:89e8c591cc58bd0e8651dddee3de290399b1ae5ad14779afe84779083fe05177 15.8 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:320d6bd226c920f6876939f87cf5d81ea00de92d4e20d226ca73562c1a1a88f6 application/vnd.oci.image.index.v1+json sha256:6b38dd347b66c7f14c393280a040831a72b4a93fd5beddc011ee852c26f35058 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed sha256:4287d3e56fdcbd36285cac0097cc79633be15d5d3ea7404ee3dd810da4804747 application/vnd.docker.distribution.manifest.list.v2+json sha256:7c5895c5d6ed3266bcd405fbcdbb078ca484688673c3479f0f18bf072d58c242 82.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:4c70d5849a8e83d95ed06d935963781239e22ce0e201cf5947149cf65c22e253 application/vnd.docker.distribution.manifest.list.v2+json sha256:39c849cebccccb22c0a5194f07c535669386190e029aa440ad535226974a5809 78.2 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed sha256:533bb34ce453f380f28c5c78664c7184ce2ef060c3be66da472cdf1b7fd7200c application/vnd.docker.distribution.manifest.list.v2+json sha256:0f0b7feb6f02620df7d493ad7437b6ee95b6d16d8d18799f3607124e501444b1 83.4 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:6a33998eca8a7ef8cbb574892c6f07420668b90164886cd09a54192a0bef91a2 application/vnd.docker.distribution.manifest.list.v2+json sha256:d2e48098c364e61ee62d9016eed863b66331d87cf67146f2068b70ed9d9b4f98 10.5 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:72c9df6be7f1b997e4a31b5cb9aa7262e5278905af97e6a69e341e3f0f9bbaae application/vnd.docker.distribution.manifest.list.v2+json sha256:94e48585629fde3c1d06c6ae8f62885d3052f12a1072ffd97611296525eff5b9 29.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:7d46a07936af93fcce097459055f93ab07331509aa55f4a2a90d95a3ace1850e application/vnd.docker.distribution.manifest.list.v2+json sha256:3d380ca8864549e74af4b29c10f9cb0956236dfb01c40ca076fb6c37253234db 247.6 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed sha256:829e9de338bd5fdd3f16f68f83a9fb288fbc8453e881e5d5cfd0f6f2ff72b43e application/vnd.docker.distribution.manifest.list.v2+json sha256:7031c1b283388d2c2e09b57badb803c05ebed362dc88d84b480cc47f72a21097 261.8 KiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,windows/amd64 io.cri-containerd.image=managed sha256:8665dd71a6e2c4c0947daaae0dc78274b869aaa50860191480c328e2cb359f49 application/vnd.oci.image.index.v1+json sha256:cb23f9634d689a4fd2c34c2132f26ddc2361f15bc6320f9682304e3503ca0056 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed sha256:8779573e497ae7fe07a121a96f3b60d262869c1803a14459e9d203ccbabbd77d application/vnd.docker.distribution.manifest.list.v2+json sha256:431f037ff18b5c867d01312e42671effc55602421aeed25dd3f6109f70596b4a 18.0 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:8e22bf689cda7eb34081c7bed8d3c97fac366b3d9b60c829a6719249f4684cd8 application/vnd.docker.distribution.manifest.list.v2+json sha256:c60778fa1c44d0c5a0c4530ebe83f9243ee6fc02f4c3dc59226c201931350b10 26.7 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:97e04611ad43405a2e5863ae17c6f1bc9181bdefdaa78627c432ef754a4eb108 application/vnd.docker.distribution.manifest.list.v2+json sha256:a0ead06651cf580044aeb0a0feba63591858fb2e43ade8c9dea45a6a89ae7e5e 13.9 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/mips64le,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:9e03e9fd536c2fc127937e4346c4bc08918fc700a35e687f1e440525a76937e7 application/vnd.docker.distribution.manifest.list.v2+json sha256:5ac2e67a862cd3baa0eb4fd7683d54928fd76ea3a61cde50508922c956901d8c 11.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:a422e0e982356f6c1cf0e5bb7b733363caae3992a07c99951fbcc73e58ed656a application/vnd.docker.distribution.manifest.list.v2+json sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c 17.5 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:abd2f13a5030c85c80dfa7b02f886470991f63f2bcf028f726e469ada5b493f6 application/vnd.oci.image.index.v1+json sha256:eed09de27648c5e13a7978069e1af63908bf4c6fd023d73de993e8b6abf556b4 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed sha256:b15a8d2801f74e271b79a7a4eef64daec0de7e18be96506b34343e4d23ae639f application/vnd.docker.distribution.manifest.list.v2+json sha256:5c3da991d54f5ff9b84e5a1fb55110b4de7fcd00723367eff6f90392ad01e79b 14.7 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:b4203935a9aeef74bbacbc7aea95f4dd36b20c61acdb93eae4f7f74cd39addbd application/vnd.docker.distribution.manifest.list.v2+json sha256:db66221bcc9510f3101121d42354b19c83cb810c5480e4936eb75c43443656f4 65.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8 io.cri-containerd.image=managed sha256:bd0140db083c4da0da65d29eac4301b34ad202134b1ef869e17ec747e1618682 application/vnd.docker.distribution.manifest.list.v2+json sha256:0ab0fafee845c82c1a31bc2a3d5df29768626d570fbbead4813ad0da4a4ebf4b 9.2 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:c727f7a87f98196c6b36fb4eb982eb1a290cb625d8239b9d0424d9f5207997e1 application/vnd.docker.distribution.manifest.list.v2+json sha256:2f34cb3a04a0fee6034f4d63ce3ee7786c0f762dc9f3bf196c70e894dd92edd1 26.4 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:d205b93c448bf3230bd9514e6d5ea32f951552c96b3693c52e5b6aaab280d2d1 application/vnd.docker.distribution.manifest.list.v2+json sha256:18632ea5cff38cda5b08054057297e527dcfc144a5f195c1c836a0805a9bbad1 4.8 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:e7f0172bd993412f6bb3e21e3edd2169d0fd92b7bb73242ee35379237625a55d application/vnd.docker.distribution.manifest.list.v2+json sha256:ebe99272d38ff65255c1fba33c17d10f588b612625b19c68fe5aeed0f134fa74 24.7 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:e81374a898b7f557718b66b4894ac3e03b90b4cb65d958ff3a35b9863f2d6ad6 application/vnd.oci.image.index.v1+json sha256:37b78640822e2563ecab155f691a2eef977472745ea09f6013e0e7f5402d64a9 247.8 MiB linux/amd64,linux/arm64,unknown/unknown io.cri-containerd.image=managed sha256:ee12b694a0f4824f5fca50ffcc95ec8c249245d8bea015944a6ca84a52ac891f application/vnd.docker.distribution.manifest.list.v2+json sha256:58d91a5faaf8f8222f8aa6c0a170826bbabcc60eedab71afd2326548cde84171 21.9 MiB linux/amd64,linux/arm,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:f410b4e37f09ec3e3aef93952fe5d161396c66754a852be2a0bc8a82de17f02b application/vnd.docker.distribution.manifest.list.v2+json sha256:a8b77a5f27b167501465f7f5fb7601c44af4df8dccd1c7201363bbb301d1fe40 83.6 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:f4937dd361b91d8b0cd79a3c0686998c912dfe874ce596de3d91357b19418e5c application/vnd.docker.distribution.manifest.list.v2+json sha256:cf169a0c328a5b4f2dc96b224c3cf6dbc2c8269c6ecafac54bc1de00102b665e 5.4 MiB linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed sha256:f9c81e42abf4293510c4cfb40720912b248ff343d94268794c74c37b58693e9a application/vnd.docker.distribution.manifest.list.v2+json sha256:c520f71091cd09a9c9628a4e010f6fbc6118da9573af46af5b3f4c3ed8d463dc 34.9 MiB linux/amd64,linux/arm64,linux/ppc64le,linux/s390x io.cri-containerd.image=managed다운로드 및 이미지 확인ctr images pull docker.io/golreas/hello:1.0.0 docker.io/golreas/hello:1.0.0: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:23e7733194ec9068106448513f45f2ae36e8931263abe26110e82c2db99549ec: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:00b6bc59183634774862a1f5d9fa777966ffdd8b4edd6fe07006671358dfc249: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:148b7926ba2143f7dbd1efaab45bd08b5fde13f01510d1319ee7cd0aa781f8d0: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:0a5428d7ed1bdde6d0638d39b519fcd3307eb60e70ba9f220d1066b39a71de93: done |++++++++++++++++++++++++++++++++++++++| config-sha256:f8812cc66e7be6bd8a78ca25a7701407a6aa40bf06d11ca572f61d63c91944a6: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:7293ae927b976710c33b54ae3957471f36b9e1150408853c3dfbd7baff3f59d1: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:34ef2a75627f6089e01995bfd3b3786509bbdc7cfb4dbc804b642e195340dbc9: done |++++++++++++++++++++++++++++++++++++++| elapsed: 12.7s total: 76.4 M (6.0 MiB/s) unpacking linux/arm64/v8 sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8... done: 1.57064216s태그 변경ctr images tag docker.io/golreas/hello:1.0.0 docker.io/golreas/hello:2.0.0 docker.io/golreas/hello:2.0.0 [root@k8s-master ~]# ctr images list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/golreas/hello:1.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 - docker.io/golreas/hello:2.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 -업로드ctr image push docker.io/golreas/hello:2.0.0 --user golreas Password: manifest-sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8: done |++++++++++++++++++++++++++++++++++++++| config-sha256:f8812cc66e7be6bd8a78ca25a7701407a6aa40bf06d11ca572f61d63c91944a6: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.0 s 이미지 -> 파일로 변환ctr -n default image export file.tar docker.io/golreas/hello:1.0.0 [root@k8s-master ~]# ls anaconda-ks.cfg file.tar k8s-local-volume k8s_env.sh k8s_install.sh monitoring 파일 -> 이미지로 변환ctr -n k8s.io image import file.tar unpacking docker.io/golreas/hello:1.0.0 (sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8)...done삭제ctr -n k8s.io image remove docker.io/golreas/hello:1.0.0 docker.io/golreas/hello:1.0.0 [root@k8s-master ~]# ctr -n k8s.io image list | grep hello 같은 이미지를 도커에서 받았을 때와 쿠버네티스에서 받았을 때 사이즈가 다른 이유dockerdocker pull 1pro/api-tester:latest latest: Pulling from 1pro/api-tester 416105dc84fc: Already exists fe66142579ff: Already exists 1250d2aa493e: Already exists 405eaf4f903e: Pull complete 4f4fb700ef54: Pull complete Digest: sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221 Status: Downloaded newer image for 1pro/api-tester:latest docker.io/1pro/api-tester:latest docker image list REPOSITORY TAG IMAGE ID CREATED SIZE 1pro/api-tester latest 320d6bd226c9 18 months ago 520MB"Architecture": "arm64", "Os": "linux", "Size": 520321200,  containerdctr image pull docker.io/1pro/api-tester:latest docker.io/1pro/api-tester:latest: resolved |++++++++++++++++++++++++++++++++++++++| index-sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221: done |++++++++++++++++++++++++++++++++++++++| manifest-sha256:95802370e0a3407e6e447de4c4ccd2a029e99eeb380b9fbf935a53cc683feed3: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1: done |++++++++++++++++++++++++++++++++++++++| config-sha256:320d6bd226c920f6876939f87cf5d81ea00de92d4e20d226ca73562c1a1a88f6: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:416105dc84fc8cf66df5d2c9f81570a2cc36a6cae58aedd4d58792f041f7a2f5: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:fe66142579ff5bb0bb5cf989222e2bc77a97dcbd0283887dec04d5b9dfd48cfa: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:1250d2aa493e8744c8f6cb528c8a882c14b6d7ff0af6862bbbfe676f60ea979e: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:405eaf4f903eeffb31e40d57d182d052fe390a30a4f401b5ec5b17f093cc61c9: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.4 s total: 0.0 B (0.0 B/s) unpacking linux/arm64/v8 sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221... done: 3.718912435s ctr image list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/1pro/api-tester:latest application/vnd.oci.image.index.v1+json sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221 247.8 MiB linux/amd64,linux/arm64,unknown/unknown -linux/amd64,linux/arm64 Container 이미지는 각각의 Layer로 구성돼 있는데, Docker에서 다운 받을 때는 전체 Layer를 받았고, Kubernetes에는 기존 이미지에 이미 존재하는 Layer가 있기 때문에 새로 받은 이미지의 Size가 작게 조회 됐을 것이다. docker -> containerddocker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 2.0.0 f8812cc66e7b 56 minutes ago 249MB golreas/api-tester v1.0.0 9438a37e6182 4 hours ago 520MB 1pro/api-tester latest 320d6bd226c9 18 months ago 520MB [root@cicd-server ~]# docker save -o docker-image.tar 1pro/api-tester:latest [root@cicd-server ~]# ls -lh docker-image.tar -rw-------. 1 root root 500M Jun 15 01:16 docker-image.tar [root@cicd-server ~]# scp docker-image.tar root@192.168.56.30:/root The authenticity of host '192.168.56.30 (192.168.56.30)' can't be established. ED25519 key fingerprint is SHA256:db7xQBeDq/ivTK1ymDqPFK0EDxCLVZfszUaoggOADiE. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.56.30' (ED25519) to the list of known hosts. root@192.168.56.30's password: docker-image.tar ctr image rm docker.io/1pro/api-tester:latest docker.io/1pro/api-tester:latest [root@k8s-master ~]# ctr image import docker-image.tar unpacking docker.io/1pro/api-tester:latest (sha256:a878b80425d48f695d8b1527fdb41d46c96fbdada66848b4b6919b44faad749d)...done [root@k8s-master ~]# ctr image list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/1pro/api-tester:latest application/vnd.docker.distribution.manifest.v2+json sha256:a878b80425d48f695d8b1527fdb41d46c96fbdada66848b4b6919b44faad749d 499.9 MiB linux/arm64 - containerd -> dockerctr image rm docker.io/1pro/api-tester:latest docker.io/1pro/api-tester:latest [root@k8s-master ~]# ctr image import docker-image.tar unpacking docker.io/1pro/api-tester:latest (sha256:a878b80425d48f695d8b1527fdb41d46c96fbdada66848b4b6919b44faad749d)...done [root@k8s-master ~]# ctr image list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/1pro/api-tester:latest application/vnd.docker.distribution.manifest.v2+json sha256:a878b80425d48f695d8b1527fdb41d46c96fbdada66848b4b6919b44faad749d 499.9 MiB linux/arm64 - docker.io/golreas/hello:1.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 - docker.io/golreas/hello:2.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 - [root@k8s-master ~]# [root@k8s-master ~]# [root@k8s-master ~]# [root@k8s-master ~]# ctr image rm docker.io/1pro/api-tester:latest docker.io/1pro/api-tester:latest [root@k8s-master ~]# ctr image pull docker.io/1pro/api-tester:latest docker.io/1pro/api-tester:latest: resolved |++++++++++++++++++++++++++++++++++++++| index-sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221: done |++++++++++++++++++++++++++++++++++++++| manifest-sha256:95802370e0a3407e6e447de4c4ccd2a029e99eeb380b9fbf935a53cc683feed3: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1: done |++++++++++++++++++++++++++++++++++++++| config-sha256:320d6bd226c920f6876939f87cf5d81ea00de92d4e20d226ca73562c1a1a88f6: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:1250d2aa493e8744c8f6cb528c8a882c14b6d7ff0af6862bbbfe676f60ea979e: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:fe66142579ff5bb0bb5cf989222e2bc77a97dcbd0283887dec04d5b9dfd48cfa: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:405eaf4f903eeffb31e40d57d182d052fe390a30a4f401b5ec5b17f093cc61c9: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:416105dc84fc8cf66df5d2c9f81570a2cc36a6cae58aedd4d58792f041f7a2f5: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.4 s total: 0.0 B (0.0 B/s) unpacking linux/arm64/v8 sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221... done: 2.824286002s [root@k8s-master ~]# ctr image list REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/1pro/api-tester:latest application/vnd.oci.image.index.v1+json sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221 247.8 MiB linux/amd64,linux/arm64,unknown/unknown - docker.io/golreas/hello:1.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 - docker.io/golreas/hello:2.0.0 application/vnd.docker.distribution.manifest.v2+json sha256:9e8c2be45e8618f075510b98d7e554d599c3ba8ed1f083faedcee243aff8e9c8 76.6 MiB linux/arm64 - [root@k8s-master ~]# ctr image export containerd-image.tar docker.io/1pro/api-tester:latest [root@k8s-master ~]# ls -lh containerd-image.tar -rw-r--r--. 1 root root 248M Jun 9 16:14 containerd-image.tar [root@k8s-master ~]# [root@k8s-master ~]# [root@k8s-master ~]# scp containerd-image.tar root@192.168.56.20:/root The authenticity of host '192.168.56.20 (192.168.56.20)' can't be established. ED25519 key fingerprint is SHA256:opQ7AT2hiB2U1FYJZyW8u3i8xsCqE91vlg6tWJRWqw0. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.56.20' (ED25519) to the list of known hosts. root@192.168.56.20's password: containerd-image.tar docker image rm 1pro/api-tester:latest Untagged: 1pro/api-tester:latest Untagged: 1pro/api-tester@sha256:189625384d2f2856399f77b6212b6cfc503931e8b325fc1388e23c8a69f3f221 Deleted: sha256:320d6bd226c920f6876939f87cf5d81ea00de92d4e20d226ca73562c1a1a88f6 Deleted: sha256:71aa8f0ba35ade0fb46725ca4f2bf964f96633622a57ad64a8c0f88475afa93a Deleted: sha256:7a611a94f41e2a6d2f0fe927f361028ae762a361f6df0c099dcfc31f1e8c168a [root@cicd-server ~]# docker load -i containerd-image.tar 34456869abea: Loading layer [==================================================>] 17.15MB/17.15MB 5f70bf18a086: Loading layer [==================================================>] 32B/32B Loaded image: 1pro/api-tester:latest [root@cicd-server ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE golreas/hello 2.0.0 f8812cc66e7b About an hour ago 249MB golreas/api-tester v1.0.0 9438a37e6182 4 hours ago 520MB 1pro/api-tester latest 320d6bd226c9 18 months ago 520MB 

데브옵스 · 인프라dockerctrbuilddevops

이상현

[인프런 워밍업 클럽 4기] DevOps 발자국 2주차

[ 강의 정보 ]강의명 : 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2 [ 워밍업 클럽 2주차 회고 ]2주차에서는 1주차에 배웠던 Pod, ReplicaSet, Deployment와 같은 Object들의 개념을 기반으로, Pod의 startup, livness, readiness Probe, Configmap, Secret, 여러 Deployment 배포 전략 그리고 Service의 기능들에 대해 알아보았다. 특히 Probe에서는 미션을 통해 잘못된 Probe 설정으로 인해 어떤 이슈 상황이 발생할 수 있는지 직접 실습해보면서, 애플리케이션에 맞는 Probe 설정이 정말 중요하겠구나 라고 다시금 생각하게 되었다. 각 Probe의 성격을 잘 이해해서 애플리케이션 마다 적절한 설정을 구성할 수 있도록 많은 실습과 테스트가 필요할 것 같다. 그리고 예전에 처음 Secret을 접했을 때, 이름에서 느껴지는 보안적인 기능 때문에 민감한 데이터는 여기에 두면 되겠다. 라고 이해할 뻔 했는데 아예 강의 하나로 빼주신 덕에 'Secret은 단순히 평문을 Base64로 암호화하는 것 뿐이다' 라는 것을 다시한번 짚고갈 수 있었다. 그 외에도 환경변수를 어떻게 관리할 것 인지 (application.yaml 혹은 configmap)를 고민하는 시간을 가져보라고 하셨는데, 개발자에게 쿠버네티스에 대한 지식을 필요하지 않게 운영한다면,, 단순히 애플리케이션 구동에 필요한 환경변수는 application.yaml 에 넣고 그 외 쿠버네티스 환경에서 돌아가기 위한 설정값은 configmap에 넣는다던가,,? 이건 아직은 감이 잘 안오긴 한다. 나중에 직접 애플리케이션을 쿠버네티스 환경을 올려서 운영해보면서 방향을 잡을 수 있지 않을까 싶다. 일단 이후 3주차에 나올 CI/CD 내용을 진행하기 전에, 2주차에 나온 개념과 여러 배포 전략들을 잘 복습해두어야겠다. 포기하지 말고 열심히 하자!인프런 워밍업 클럽 4기 블로그 시리즈

데브옵스 · 인프라kubernetedevops

David

[인프런 워밍업 클럽 4기 - DevOps] 미션 4

PV, PVC1번 API 파일 생성[root@k8s-master ~] curl http://192.168.56.30:31231/create-file-pod hrgosbpjox.txt [root@k8s-master ~] curl http://192.168.56.30:31231/create-file-pv xprrmxjsna.txt2번 Container 임시 폴더 확인[root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-5krzn -- ls /usr/src/myapp/tmp hrgosbpjox.txt [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-5krzn -- ls /usr/src/myapp/files/dev xprrmxjsna.txt [root@k8s-master ~] ls /root/k8s-local-volume/1231/ xprrmxjsna.txt2번 master node 폴더 확인[root@k8s-master ~] ls /root/k8s-local-volume/1231/ xprrmxjsna.txtpod 삭제[root@k8s-master ~] k delete -n anotherclass-123 pod api-tester-1231-66c489cbb8-5krzn pod "api-tester-1231-66c489cbb8-5krzn" deleted4번 API - 파일 조회[root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-9kpxd -- curl localhost:8080/list-file-pod [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-9kpxd -- curl localhost:8080/list-file-pv xafgvinxxz.txt thschtbuoo.txt pablwvxlec.txt pogdzjqhqs.txt xprrmxjsna.txt 5. hostPath 동작 확인 - Deployment 수정 후 [1~4] 실행apiVersion: apps/v1 kind: Deployment metadata: namespace: anotherclass-123 name: api-tester-1231 spec: template: spec: nodeSelector: kubernetes.io/hostname: k8s-master containers: - name: api-tester-1231 volumeMounts: - name: files mountPath: /usr/src/myapp/files/dev - name: secret-datasource mountPath: /usr/src/myapp/datasource volumes: - name: files persistentVolumeClaim: // 삭제 claimName: api-tester-1231-files // 삭제 // 아래 hostPath 추가 hostPath: path: /root/k8s-local-volume/1231 - name: secret-datasource secret: secretName: api-tester-1231-postgresql[1~4 반복]API - 파일 생성 [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-9kpxd -- curl localhost:8080/list-file-pod [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-66c489cbb8-9kpxd -- curl localhost:8080/list-file-pv xafgvinxxz.txt thschtbuoo.txt pablwvxlec.txt pogdzjqhqs.txt xprrmxjsna.txt Container 임시 폴더 확인 root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-7gtwq -- ls /usr/src/myapp/tmp yrwjythrtf.txt Container 영구저장 폴더 확인 [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-7gtwq -- ls /usr/src/myapp/files/dev lbjgryyqvl.txt pogdzjqhqs.txt xafgvinxxz.txt pablwvxlec.txt thschtbuoo.txt xprrmxjsna.txt Master node 폴더 확인 [root@k8s-master ~] ls /root/k8s-local-volume/1231 lbjgryyqvl.txt pablwvxlec.txt pogdzjqhqs.txt thschtbuoo.txt xafgvinxxz.txt xprrmxjsna.txt API - 파일 조회 root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-7gtwq -- curl localhost:8080/list-file-pod yrwjythrtf.txt [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-7gtwq -- curl localhost:8080/list-file-pv lbjgryyqvl.txt xafgvinxxz.txt thschtbuoo.txt pablwvxlec.txt pogdzjqhqs.txt xprrmxjsna.txt RollingUpdate 하기HPA minReplica 2로 바꾸기 [root@k8s-master ~] k patch -n anotherclass-123 hpa api-tester-1231-default -p '{"spec":{"minReplicas":2}}' horizontalpodautoscaler.autoscaling/api-tester-1231-default patched 그외 Deployment scale 명령 [root@k8s-master ~] k scale -n anotherclass-123 deployment api-tester-1231 --replicas=2 deployment.apps/api-tester-1231 scaled edit로 모드로 직접 수정 kubectl edit -n anotherclass-123 deployment api-tester-1231 지속적으로 Version호출 하기 while : do curl http://192.168.56.30:31231/version sleep 2 echo '' done 3) 별도의 원격 콘솔창을 열어서 업데이트 실행 kubectl set image -n anotherclass-123 deployment/api-tester-1231 api-tester-1231=1pro/api-tester:v2.0.0 kubectl set image -n anotherclass-123 deployment/api-tester-1231RollingUpdate (maxUnavailable: 0%, maxSurge: 100%) 하기strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0% maxSurge: 100% kubectl set image -n anotherclass-123 deployment/api-tester-1231 api-tester-1231=1pro/api-tester:v1.0.0 Recreate 하기 strategy: type: Recreate [root@k8s-master ~] kubectl set image -n anotherclass-123 deployment/api-tester-1231 api-tester-1231=1pro/api-tester:v2.0.0 deployment.apps/api-tester-1231 image updated Rollback[root@k8s-master ~] kubectl rollout undo -n anotherclass-123 deployment/api-tester-1231 deployment.apps/api-tester-1231 rolled back ServicePod 내부에서 Service 명으로 API 호출[root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-88cqq -- curl http://api-tester-1231:80/version [App Version] : Api Tester v1.0.0 Deployment에서 Pod의 ports 전체 삭제, Service targetPort를 http -> 8080으로 수정apiVersion: apps/v1 kind: Deployment metadata: namespace: anotherclass-123 name: api-tester-1231 spec: template: spec: nodeSelector: kubernetes.io/hostname: k8s-master containers: - name: api-tester-1231 ports: // 삭제 - name: http // 삭제 containerPort: 8080 // 삭제 --- apiVersion: v1 kind: Service metadata: namespace: anotherclass-123 name: api-tester-1231 spec: ports: - port: 80 targetPort: http -> 8080 // 변경 nodePort: 31231 type: NodePort [root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-88cqq -- curl http://api-tester-1231:80/version [App Version] : Api Tester v1.0.0 HPA[root@k8s-master ~] k top -n anotherclass-123 pods NAME CPU(cores) MEMORY(bytes) api-tester-1231-6cf7495fcd-88cqq 1m 140Mi [root@k8s-master ~] k top -n anotherclass-123 pods NAME CPU(cores) MEMORY(bytes) api-tester-1231-6cf7495fcd-88cqq 104m 161Mi [root@k8s-master ~]# k get hpa -n anotherclass-123 NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE api-tester-1231-default Deployment/api-tester-1231 56%/60% 2 4 2 3d8h [behavior] 미사용으로 적용spec: # behavior: # scaleDown: # policies: # - periodSeconds: 15 # type: Percent # value: 100 # selectPolicy: Max # scaleUp: # policies: # - periodSeconds: 15 # type: Pods # value: 4 # - periodSeconds: 15 # type: Percent # value: 100 # selectPolicy: Max # stabilizationWindowSeconds: 120 [root@k8s-master ~] kubectl edit -n anotherclass-123 hpa api-tester-1231-default horizontalpodautoscaler.autoscaling/api-tester-1231-default edited부하 발생 API[root@k8s-master ~] k exec -n anotherclass-123 -it api-tester-1231-6cf7495fcd-88cqq -- curl http://192.168.56.30:31231/cpu-load[root@k8s-master ~] k get hpa -n anotherclass-123 NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE api-tester-1231-default Deployment/api-tester-1231 101%/60% 2 4 4 3d8h [root@k8s-master ~] k top -n anotherclass-123 pods NAME CPU(cores) MEMORY(bytes) api-tester-1231-6cf7495fcd-5b6bw 202m 157Mi api-tester-1231-6cf7495fcd-88cqq 1m 140Mi api-tester-1231-6cf7495fcd-br5d2 1m 127Mi api-tester-1231-6cf7495fcd-wzx9k 1m 127Mi       

데브옵스 · 인프라devopsk8shpapvpvcservicerolling

kndh2914

인프런 워밍업 클럽 4기 - DevOps 2주차 발자국

[2주차 강의 수강]2주차 기간동안 k8s의 applicaition 기능으로 k8s를 이해하는 시간을 가졌다. 또한 실습시간에 k8s의 기능들을 보다 제대로 활용하기 위해 많이 활용하면서 장난감 다루듯이 마구잡이로 다뤘던 시간들을 경험하게 되었다. 미션과제도 해보고 실습을 따라해보면서 완벽하게 해보지는 못했지만 따로 복습시간을 가지면서 더욱 더 k8s를 이해하게 되었고 실무에 나갔을 때도 확실하게 다룰 수 있도록 배우는 자세를 가지게 되었다.[미션] [2번미션]링크: https://du-hyeon.notion.site/5-Application-1-Probe-20722449e85a8014a350c93b419f22ec?source=copy_link [3번미션]링크:https://du-hyeon.notion.site/6-Application-2-Configmap-Secret-20722449e85a80c3a914c3b9ae1e043b?source=copy_link [4번미션]링크: https://du-hyeon.notion.site/7-Application-PV-PVC-Deployment-Service-HPA-20822449e85a8015ad0de48924b42dbe?source=copy_link  회고: 2주차에는 미션이 3개이면서 많은 실습시간을 투자한 기간이였을뿐더러 더욱 더 손에 익히고 눈으로 많이 보게되면서 k8s의 구조와 어떠한 상황에서 기능을 써야 더 좋은 시너지가 일어나는지에 대한 시간을 가지게 되었다. 다음주부터는 3주차이고 벌써 스터디의 절반이 지났다고 한다. 또한 3주차부터는 Sprint2로 넘어가기 때문에 더더욱 설레는 마음으로 공부를 할 계획이다.

데브옵스 · 인프라k8s인프라일프로devops화이팅워밍업클럽4기

David

[인프런 워밍업 클럽 4기 - DevOps] 미션 3. Configmap, Secret

▶ 응용1 : Configmap의 환경변수들을 Secret을 사용해서 작성하고, App에서는 같은 결과가 나오도록 확인해 보세요.☞ Secret을 이렇게 사용하는 경우는 별로 보지 못했습니다. 여러가지 방법으로 Secret을 만들어본다는데 의의를 두시면 됩니다. Secret 생성 (1) - Dashboard확인을 위해 Dashboard에서 Secret 선택CMD 확인Deployment에서 envFrom 수정▶ 응용2 : 반대로 Secret의 DB정보를 Configmap으로 만들어보고 App을 동작시켜 보세요☞ Configmap을 Volume에 연결해서 쓰는 케이스는 매우 많습니다. apiVersion: v1 kind: ConfigMap metadata: namespace: anotherclass-123 name: api-tester-1231-postgresql labels: part-of: k8s-anotherclass component: backend-server name: api-tester instance: api-tester-1231 version: 1.0.0 managed-by: dashboard data: postgresql-info.yaml: | driver-class-name: "org.postgresql.Driver" url: "jdbc:postgresql://postgresql:5431" username: "dev" password: "dev123"  volumes: - name: files persistentVolumeClaim: claimName: api-tester-1231-files - name: configmap-datasource configMap: name: api-tester-1231-postgresql defaultMode: 420 ... volumeMounts: - name: files mountPath: /usr/src/myapp/files/dev - name: configmap-datasource mountPath: /usr/src/myapp/datasource/dev

데브옵스 · 인프라k8s인프런devopssresecretconfigmap쿠버네티스

wnsrlf0721

[워밍업 클럽: 쿠버네티스] #2. 쿠버네티스 무게감 있게 설치하기 (1주차)

강의 수강 일자 : 25.05.28 (수)블로그 복습 일자 : 25.05.30 (금), 25.05.31(토) 이번 내용에선 쿠버네티스를 내 PC상에 설치를 하는 과정을 복습하면서, 당시에 썻던 스크립트 내용을 하나하나 뜯어보고,왜 이런 스크립트 코드를 썼는지, 실제로 강의의 흐름 없이 쿠버네티스를 내가 직접 설치한다는 가정 하에 복습을 해보겠다. 쿠버네티스를 사용하는 전체 환경 그려보기1) 개발 환경스프링부트와 인텔리제이로 자바 어플리케이션 개발을 하게 되면,Gradle 빌드 툴은 Maven에서 라이브러리를 다운 받아 자바 소스코드를 컴파일해 JAR 파일을 빌드해 JVM 환경에서 실행한다.개발을 완료한 소스코드는 GitHub 저장소에 올리고, 저장소에 올린 소스코드는 CI/CD 환경에서 자동으로 통합과 배포를 진행할 수 있다. 2) CI/CD 환경Jenkins는 내 컴퓨터 환경이 아닌 가상 서버(VM)에서 동작한다.GitHub 소스코드를 다운받고, 해당 환경에 있는 Gradle에 관련 라이브러리를 Maven에서 받는다.Gradle을 통해 소스코드를 빌드해 JAR파일을 만든다.이제 컨테이너 빌드를 하게 될 텐데,먼저 JAR 파일을 실행시킬 OpenJDK 이미지를 도커 허브에서 다운로드 받습니다(도커 허브는 컨테이너 이미지 저장소).이 이미지는 내 JAR 파일을 띄우기 위한 기반이 될 건데, 이를 베이스 이미지라 합니다.베이스 이미지에 JAR 파일을 올리는 걸 완료하면 컨테이너 빌드가 끝납니다.컨테이너 빌드로 생성된 이미지를 다시 도커허브에 올리는 과정까지가 젠킨스에서 빌드를 했을 때 일어나는 과정입니다.이제 배포과정만 남았는데, 배포는 쿠버네티스 측에 Pod 생성 명령을 보내주는 것이 끝입니다.이후에는 인프라 환경 측에서 동작을 합니다. 3) 인프라 환경Pod 생성 명령에는 컨테이너 이미지 주소가 들어있습니다. 쿠버네티스는 주소를 보고 해당 이미지를 다운로드 받게 되고,해당 이미지로 컨테이너를 생성하는 요청을 컨테이너 런타임에 보내줍니다. 개발 환경에는 여러 사람들이 모여 개발한 소스를 GitHub 저장소에 올리고, CI/CD 환경에서 해당 소스코드를 컨테이너 이미지로 인프라 환경에 보내줍니다. 인프라 환경에는 개발, 검증, 운영 환경으로 나눠져 있습니다. 실습에서 진행할 환경 흐름 실습에서는 인프라 환경만 구축을 한다.인프라 구축을 완료하면 브라우저에서 대시보드로 접속을 해 쿠버네티스 오브젝트를 생성할 수 있고,원격 접속 툴로 쿠버네티스가 설치된 OS에 접근을 하면, kubectl을 통해 CLI 통신으로 쿠버네티스에 명령을 보낼 수 있다. 쿠버네티스 설치 및 스크립트 해석하기쿠버네티스 설치개인 PC에 가상환경 VMBox와 Vagrant를 설치하고, 스크립트로 쿠버네티스까지 설치해볼 수 있다.진행한 PC의 OS는 Window10 을 기준으로 진행했습니다. 설치하는 과정은 뇌를 빼고 따라오고, 나중에 미션에서우리가 설치한 것들을 하나하나 살펴볼 예정이니 잘 따라오면 됩니다 ㅎㅎ.. 그럼 시작하겠습니다. Virtual Box 설치 (설치 당시 v7.1.6)https://www.virtualbox.org/wiki/DownloadsVirtualBox 공식 사이트에서 제공하는 다운로드 링크입니다. 들어가면이렇게 PC의 OS 환경에 맞게 VirtualBox를 설치하라고 친절하게 설명 되어있습니다.윈도우 OS에서 설치할 거니 Windows hosts를 눌러 설치해줍니다. Vagrant 설치 (v2.4.3)https://developer.hashicorp.com/vagrant/install?product_intent=vagrantVagrant도 마찬가지로 각 PC의 OS 환경에 맞는 소프트웨어를 제공해주기 때문에, 마찬가지로 윈도우 버전를 선택해 다운 받으면 됩니다. Vagrant 관련 스크립트 다운로드 및 실행윈도우 검색창에 명령 프롬프트를 선택해 아래 스크립트를 그대로 따라 치면 됩니다.# Vagrant 폴더 생성 C:\Users\사용자> mkdir k8s && cd k8scmd에서 현재 위치는 C:\Users\사용자> 이고, 해당 위치에 k8s 폴더를 생성한 후 해당 폴더로 이동하는 명령입니다. # Vagrant 스크립트 다운로드 curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/vagrant-2.4.3/Vagrantfilecurl는 url을 통해 데이터를 다운받을 수 있게 하는 명령이다. 위 명령어를 따라 치면k8s 폴더에 Vagrantfile이 다운받아져 있다.실제로 안에 있는 스크립트 내용이 궁금하다면 들어가서 보고오자.https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/vagrant-2.4.3/Vagrantfile # Rocky Linux Repo 세팅 curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/k8s-1.27/vagrant-2.4.3/rockylinux-repo.json vagrant box add rockylinux-repo.json 윗 부분과 마찬가지로 이번에는 json 파일을 다운로드 받았다.# Vagrant Disk 설정 Plugin 설치 vagrant plugin install vagrant-vbguest vagrant-disksize # Vagrant 실행 (VM생성) vagrant up위 명령어들을 다 따라하고 나면, k8s에 아래와 같이 파일들이 있으면 정상적으로 실행된거다. vagrant up을 했을 때 뭔가 프롬프트 환경에서 잘 설치가 안된거 같다고 생각이 든다면https://cafe.naver.com/kubeops/26 이 링크에 가서 오류를 해결할 방법을 찾아보자 😂 MobaXterm 설치https://mobaxterm.mobatek.net/download-home-edition.html3단계까지 무사히 잘 마치고, MobaXterm 설치까지 완료 된다면, 우리는 쿠버네티스 환경을 설치한 가상OS에 접속하거나, 할당된 IP로 접근해 쿠버네티스 대시보드까지 확인 가능하다. MobaXterm으로 원격 접속하기- Sessions>New session을 선택해서 접속 세션 생성- 최초 id는 root,password는 vagrant 입니다.세션을 새로 만든 뒤 실행을 하면 프롬프트처럼 검은 화면이 보일 거다.MobaXterm은 쿠버네티스가 설치된 가상 OS에 접근해 쿠버네티스 관련 Pod를 볼 수 있다.혹시라도 Vagrant Up 이후 PC를 종료하면 가상OS가 꺼지니 이후에 가상OS를 키려면다시 cmd 창에 vagrant up을 키면 가상OS를 재기동할 수 있습니다 :D 쿠버네티스 DashBoard 확인하기https://192.168.56.30:30000/#/login링크에 들어가면 쿠버네티스 DashBoard를 확인할 수 있고, 클러스터 노드들을 보게 됩니다. 쿠버네티스를 설치하는 부분까지 잘 따라왔으면, 이제 미션을 따라해볼 수 있습니다!아래 링크에 들어가 미션을 따라하면 쿠버네티스를 설치하는 흐름이 보이고, 강의에서 제공하는 스크립트 코드가 쿠버네티스 공식 문서의 흐름대로 따라가고 있음을 알 수 있습니다!https://inf.run/svj7j

k8scontainerdevops

채널톡 아이콘