kubescape 의 prometheus / lens 지원 소식

Kubescape now integrates with Prometheus and Lens | ARMO (armosec.io)

prometheus

kubescape 에 취합된 각 노드별 취약점 점수가 prometheus 를 통해 시계열화 되고

# Overall riskScore of the scan
kubescape_cluster_riskScore{} <risk score>

cluster riskScore 를 grafana 에 보여줄 수 있다. 즉, kubescape 의 dashboard 를 grafana 에 통합할 수 있다는 얘기

lens

k8s 계의 IDE 라 불리는 lens 에도 kubescape 의 지표를 표시할 수 있게 되었다.

kubescape – k8s 종합 보안 점검 도구

개요

kubespace 는 통합관리화면을 통해서 k8s 멀티 클라우드 보안 취약점을 스캐닝하고 RBAC 설정을 시각화 하며, 컨테이너 이미지를 스캐닝한다. kubescape 는 k8s 클러스터와 yaml 파일과 HELM charts 를 다양한 보안 프레임워크를 이용해서 잘못 설정된 부분을 검사하며 s/w 취약점, ci/cd 파이프라인 초기단계의 RBAC 오류, 위험점수를 즉시 계산하며 위험추세도 보여줍니다. k8s 에서 가장 빠르게 성장하는 툴이며 개발자에게 친숙한 CLI, 유연한 포멧, 자동 스케닝 기능을 제공하여 k8s 사용자들에게 시간,노력을 아끼게 해줍니다. kubescape 는 jenkins, circleCI, github workflows, Prometheus, slack 과 같은 DevOps 툴들과 통합되며 EKS, GKE, AKS 와 같은 다중 클라우드 k8s 배포를 지원합니다.

기본적인 scan 명령을 통해 클러스터의 종합 평가를 즉각 수행할 수 있다.
간단한 명령 복사 붙여넣기를 통해 클러스터 점수를 dashboard 로 전송할 수 있다.
RBAC visualizer 을 통해 시각화된 권한 체크를 할 수 있음

상용툴로는 Prisma Cloud | Comprehensive Cloud Security – Palo Alto Networks 가 있다.

vscode plugin 으로 live scanning

vscode plugin

vscode 에 kubescape plugin 을 설치하면 yaml 개선 포인트를 즉각 감지 할 수 있다. 따라서 아직 commit 되지 않은 yaml / helm chart 를 검사 가능하다.

yaml 작성시 개발자가 commit 하기 전에 스스로 보안취약점을 점검/개선 할 수 있다.

refs.

(2880) Kubescape walkthrough – Easy Kubernetes security tool – YouTube

armosec/kubescape: Kubescape is a K8s open-source tool providing a multi-cloud K8s single pane of glass, including risk analysis, security compliance, RBAC visualizer and image vulnerabilities scanning. (github.com)

k8s VM 재기동 데몬 kured, k8s reboot daemon

refer

개요

보안 등의 이슈로 k8s worker node는 항상 최신 버전으로 업그레이드 되어야 하며, 가끔은 VM 그 자체를 리붓해야 하는 경우가 생긴다. (정기 PM 등의 목적)

kured

kured 는 k8s reboot daemon 으로 helm 으로 쉽게 설치하여 daemonset 으로 구동시킬 수 있다. (모든 노드에서 동작하도록 하기 위해)

다양한 설정을 통해 리붓이 필요한 상태인 VM 을 스케쥴에 맞추어 리붓이 가능하도록 도와준다. (기본적으로 60분에 한번씩 체크한다) apt update 등을 진행할 때 linux 가 스스로 reboot 이 필요한 상태임을 알리는 mark file (/var/run/reboot-required) 이 생성되는 데 kured는 host 파일을 모니터링하여 지정된 시간에 리붓을 할 수 있다. daemonset 으로 설치하는 이유가 이것 때문이겠다. 모든 node가 동시에 리붓되면 안되니까.

Polaris, k8s 리소스 설정 검사 툴 소개

개요

쿠버네티스는 강력한 s/w 배포 플랫폼이다. 유연성이 높아 어떤 유즈케이스도 이루어 낼 수 있다. fortune 500 기업중 절반이 k8s 를 도입한 이유! Dimensional Research and VMware 연구 ( https://k8s.vmware.com/state-of-kubernetes-2020/ ) 에 따르면 k8s 도입 증가율은 폭발적이다.

그러나 모든 툴들이 그렇듯. 강력함과 보안은 서로 상충한다. 수백만의 다양한 방식의 k8s 설정으로 실행중인데 99%는 위험하다. 보안과점, 효율적인 관점, 그리고 신뢰도 측면에서 쉽게 설명 가능하다. 간혹 YAML 설정의 일부를 누락하기 때문에

이 이슈에 대응하기 위해, 커뮤니티는 k8s 워크로드를 설정하는 best practice 를 생각해 냇다. 이 가이드라인은 항상 따라야 하고 따르지 않을 이유가 없다.  Fairwinds’ Polaris project 는 이것들을 돕고 강제하기 위해 만들어졌다.

예제

k8s deployment 예제다.

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

뭐가 잘못되었는지 생각해 보세요, 아마도 못할 것입니다. 여기에는 심각한 문제를 야기할 수 있는 문제들이 있습니다.

CPU 와 메모리 설정

우선, k8s 에서는 얼마나 많은 메모리와 cpu 가 사용될 것인지 예측하는게 중요하다. 이것은 k8s 에게 어떤 worker node 에서 효율적으로 배치할 수 있게 해준다. 그리고 이는 어플리케이션의 비정상 작동에 대한 지침이 될 수 있다.

      containers:
      - name: nginx
        image: nginx:1.14.2
        resources:
          requests:
            memory: 512MB
            cpu: 500m
          limits:
            memory: 1GB
            cpu: 1000m

Health Probes

위의 예제는 또한 Liveness 와 Readness Probe 설정이 누락되엇다. 이 설정들은 k8s 가 어플리케이션이 요청을 받아들일 준비가 되어 있는지를 확인하는 방법에 대한 것이다. LivenessProbe 가 없다면, k8s 는 어플리케이션이 응답을 안 할 때 자동 회복하지 않을 것이다. ReadnessProbe 설정이 없다면 pods 이 완전히 제대로 기동 되었는지의 여부를 알 수 없다.

Liveness 와 Readiness Probes 는 어플리케이션 동장에 대한 지식이 있어야 한다. 그러나 특정한 HTTP endpoint 를 호출해 보거나 unix command 를 실행하는 것만으로 적절히 동작하는지를 테스트 해볼 수 있다.

      containers:
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080

보안 요소

많은 k8s 워크로드 설정은 기본적으로 보안 없이 설정된다. 어플리케이션이 필요할 지도 아닐지도 모르는 권한을 부여할 지도 모른다. 예를 들어 모든 컨테이너는 root 파일시스템을 수정할 수 있는 권한을 기본적으로 가진다. 이것은 공격자가 시스템의 바이너리를 수정하거나 설정을 수정할 수 있다

더 안전한 설정이라면 아래의 내용을 가져야 할 것이다.

      containers:
      - name: nginx
        image: nginx:1.14.2
        securityContext:
          allowPrivilegeEscalation: false
          privileged: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          capabilities:
            drop:
              - ALL

Polaris 가 돕는 방법

Polaris 는 위의 내용을 포함해서 더 많은 것들을 검사한다. 2021년 5월 기준 24가지의 종류를 체크하고 여러 커뮤니티의 피드백으로 검사 종류가 더 추가되고 있다.

각각의 체크는 JSON 스키마로 작성되었다. kubectl 명령 실행시마다 동작한다. 가장 간단한 예제는 아래와 같다.

successMessage: Host network is not configured
failureMessage: Host network should not be configured
category: Security
target: Pod
schema:
  '$schema': http://json-schema.org/draft-07/schema
  type: object
  properties:
    hostNetwork:
      not:
        const: true

JSON 스키마와 Go 템플릿으로 꽤 복잡한 문법을 체크한다.  the Polaris documentation 를 읽어보면 커스텀 Polaris checks 를 직접 만들 수도 있다. 이것은 당신의 조직의 내부 정책을 구현하여 best practice 를 강제하는데 도움이 될 것이다.

Polaris configuration 을 설정하고 나면 (기본 설정도 꽤 괜찮다.) Polaris 는 3가지 모드로 작동한다.

  • Dashboard – 클러스터내의 어떤 리소스가 개선되어야 하는지
  • Admission Controller – 문제가 많은 리소스는 클러스터에 배포 되는 것을 방지
  • CI/CD – 체크인 되기 전에 코드로서의 인프라 검사

자신있는 배포

k8s 는 강력하며, 강력함에는 큰 책임감도 따른다. 따라서 k8s 배포전에 best practice 를 따르는 것은 중요하다. 설정을 소홀히 하면 보안 결함과, 운영의 문제와, 클라우드인 경우에는 비용이 과다지출 될 수도 있다.

CI/CD 과정에, Admission Control 로서 또는 수정적으로 확인할 Dashboard 역할로 Polaris 를 당신의 workflow 에 넣게되면, 자신있게 위험수위를 체크하는데 도움이 될 것이다. 그리고 poliris 를 cluster 전반에서 활용하고자 할 때 Trivy 와 같은 이미지 스캐닝 도구나 Goldilocks 와 같은 메모리/ cpu 설정의 적정 사이즈를 제시하는 툴과 같은 역할을 하는 도구를 같이 써도 좋고 k8s 의 audinting 과 정책을 강제 하는 Fairwinds Insights 도 알아보라

너가 k8s 전문가일수도 있고 처음 클러스터를 설계할 수도 있을텐데 일종의 가드레일을 준비해야 한다. Fairwind 사의 Polaris 와 Insights 는 좋은 출발점이다.

refs.

CKS – Certified Kubernetes Security Specialist 합격 수기

Certified Kubernetes Security Specialist (CKS) Exam | Linux Foundation

CKAD, CKA 에 이어 CKS 도 pass 했습니다. CKS는 kubernetes 환경에서 OS 부터 시작해서 POD 레벨 container 레벨 docker image 레벨까지 각각의 요소의 취약점을 파악하는 방법을 알아보고 어떤 문제가 있으며 어떻게 해결하면 좋은지 그리고 자동화된 분석도구를 사용해 보도록 가이드 합니다.

무엇을 알게되는가?

CKS 를 취득하면서 배우면 k8s 를 도입하면 각 영역마다 어떤 부분을 체크해야 하는지 어떤 부분이 보안상 취약할 수 있는지를 전체적으로 바라보고 가이드 할 수 있는 역량을 취득할 수 있습니다.

kube-bench, trivy 등으로 각node 와 container image 취약점을 자동 스케닝 하고 Dockerfile 과 kubernetes yaml 파일을 직접 (manually) 점검하는 방법도 익혀야 합니다. 또한 RBAC 을 통한 세부적인 권한 관리와 audit log 를 설정하여 이상 징후를 감지하고 찾아내는 방법도 익힐 수 있습니다.

해킹과 방어, 창과 방패의 싸움에서 해킹은 점점 강해지고 방어하는 기술도 점점 진화해야 합니다. 한순간에 익힌 보안 기술이 전부가 아니겠습니다. CKAD와 CKA 는 3년의 자격 유지가 인정되는 반면 CKS 는 2년의 자격 유지가 인정됩니다. 2년 후에는 새로운 보안 기술을 익혀야 하며, 2년이 지난 보안 기술은 자격자로 인정하기 어렵다는 뜻이겠습니다.

공부 방법과 걸린 시간 간단한 소회

CKAD, CKA 를 공부하게 되면 기본적으로 kubernetes document 를 검색하고 사용하는 방법 yaml 작성 능력과 vim 사용능력을 키우게 되므로 회사 생활과 병행하며 CKS자격을 취득하는 대는 약 한 달의 시간이 소요되었던 것 같습니다. 주말에는 아내가 공부하는 시간을 많이 배려해 주었습니다.

udemy 강의를 구독하여 1차례 수강 후 강사가 제공하는 killer.sh 에서 각 챕터별 실습을 하였고 시험 결제를 하면 총 2회의 모의고사 (같은 문제) 를 풀 수 있습니다. 처음에는 40점이 나왔으나 그냥 꾸준히 틀린 문제를 반복하여 100점에 나올 때 까지 session reset (문제를 풀고 있는 VM 을 초기화) 을 통해 각 문제에서 모른 부분은 더이상 없도록 할 때까지 반복해서 풀었습니다. 이 때 애매한 개념들이 많이 해소 되었습니다.

https://www.udemy.com/course/certified-kubernetes-security-specialist

시험에 출제된 내용과 과정, 시험팁

시험에는 gviser 설정, trivy 돌려보기, docker 및 pod 취약점 있을 만한 것 찾기, pod security policy 구성, RBAC role / clusterrole binding, OPA, CKA 에 자주 등장한 network policy, ETCD를 이용한 secret 찾기 base64 decode 하기 등

공부했던 거의 모든 부분이 출제 되었습니다. 특히 kube-apiserver 취약 설정 찾아내서 고치는 부분의 경우 manifest 의 pod이 재시작 되고 항상 잘 기동되길 바라는 마음을 가져야 했습니다.

docker 가 아닌 crictl 로 구동 되기에 watch -n 0.5 crictl ps 명령을 자주 사용 하여 kube-apiserver 가 재기동 되는 순간을 알아낼 수 있었습니다. 지금에서야 느끼는데 kube-apiserver 가 죽는데는 거의 10~15 초가 걸리고, 되살아나는대는 2~3초 밖에 안 걸린다는 점입니다. udemy 강사는 4~5 초만에 재기동 되는 것 같은데.. 시험보는 VM 서버는 사양이 좋지 않은 모양입니다. 그래서 manifest 를 수정 후, watch -n 0.5 crictl ps 를 치면서 그야말로 그냥 기다리는 시간은 좀 아깝다고 느껴졌습니다. (그래서 다음 문제를 먼저 살펴보기도 했습니다.)

시험 보는 중에 trivy 나 gviser 문제에서 해당 document 는 탭으로 하나 더 열어도 된다 라는 내용을 보고 k8s document 외에 2개의 탭을 더 열게 되었는데 감독관이 10분 후쯤에 화면을 잠구더니 그러지 말라 해서 그냥 알겠다고 하고 닫았더니 문제는 없었습니다. 그러니까…. 10분 정도는 감독관이 못 본 것 같고 실시간 감시도 아닌 것 같습니다.

만약 시험이 떨어지게 되면, 거의 비슷한 출제 내용으로 1번 공짜로 볼 수 있습니다. 그래서 자격증만을 위해서 시험을 치루는 경우라면 어서빨리 시험을 보고, 패턴을 익혀서 한주 후 쯤에 또 치루는 것도 방법일 수는 있겠습니다.

마치며

digital badges 를 모으는게 새로운 취미가 된 것 같은데 다음 자격증으로는 elastic search 사의 자격증을 따보려고 합니다. 업무상 kibana 를 많이 사용하는데 로그를 검색 하는 것이 아닌 분석하는 사람이 되고 싶습니다.

elastic 사의 자격증 3가지

elastic 사에서의 3가지 자격증 코스를 운영하고 있다.
Onsite & Online Training for Elasticsearch, Kibana, Beats, Logstash, and more | Elastic Training

Elasticsearch Engineers

클러스터를 관리하고 ES 를 이용해 새로운 검색엔진 구축합니다.

이 자격은 그들의 데이터를 indexing, searching, managing 할 수 있는 다재다능한 Elasticsearch 전문가입니다.

Data Analyst

ES에 적재된 데이터를 이용해 kibana 를 통해 시각화하며 분석합니다.

분석 전문가는 kibana 를 이용해 데이터를 가시적으로 표현하고 분석합니다. 시시각각 변하는 데이터를 분석해 강력한 데시보드를 만들며, 이것으로 머신러닝 작업을 개발할 수 있습니다.

Observability Engineers

로그와 각종 지표, APM 추적결과를 통합하고 시스템 전반의 상태를 관찰할 수 있습니다.

iframe 현대닷컴

redis data migration 레디스 마이그레이션 rump? redis-shake! 쓰자!!

데이터를 무중단으로 migration 해야 할 일이 생겼다. 알아보니 rump 가 있다.

https://github.com/stickermule/rump

새로운 redis 서버로의 데이터 이관을 위해서 기존 서버의 사용은 유지한채 새로운 서버로 데이터를 이관해야 하는 상황

인프라 팀에서는 데이터 이관을 지원해 주지 않은다고 하고 해봤자 *.aof 파일을 복제해서 다시 켜주는 수준

개발자로서 데이터 이관을 알아봐야 하는 상황이었다.

test redis 2개 기동

일단 docker 를 이용해 2개의 redis 를 기동했다. 성능을 올리기 위해서 cpu 와 memory 옵션을 사용한다.

docker run –name redis1 -p 6379:6379 –rm –cpus=4 -m=8g redis

docker run –name redis2 -p 6389:6379 –rm –cpus=4 -m=8g redis

샘플 데이터 입력

https://github.com/nzin4x/import-redis-by-python

위의 코드를 이용해 100만건의 데이터를 넣었다. 약 14분 소요.

RUMP 로 데이터 복제 (비추)

rump 로 data 를 복제한다. rump 를 다운로드 받아서 바로 실행

redis1 의 0 번 DB의 내용을 redis2 의 1번 DB로 복제 하는 코드

curl -SL https://github.com/stickermule/rump/releases/download/1.0.0/rump-1.0.0-linux-amd64 -o rump
./rump -from redis://localhost:6379/0 -to redis://localhost:6389/1 -silent

wsl 이 있어서 얼마나 다행인지 windows 는 좋은 linux 머신이다.

Rump 가 너무 느려서 좀 알아보니

알리바바 그룹의 천재들이 만든 redis-shake 를 알아냈다.

redis-shake! 가 답이다.

sync 중에 원본 redis (redis1) 에 키 입력/조회도 되고 (실시간 사용 및 복제 가능) 속도가 엄청 빠르다.

nz@nzMain:/mnt/c/Users/nzin4/release-v2.1.1-20210903$ ./redis-shake.linux -conf redis-shake.conf -type sync
2022/03/09 21:20:06 [WARN] source.auth_type[auth] != auth
2022/03/09 21:20:06 [WARN] target.auth_type[auth] != auth
2022/03/09 21:20:06 [INFO] input password is empty, skip auth address[127.0.0.1:6389] with type[auth].
2022/03/09 21:20:06 [INFO] input password is empty, skip auth address[127.0.0.1:6379] with type[auth].
2022/03/09 21:20:06 [INFO] input password is empty, skip auth address[127.0.0.1:6379] with type[auth].
2022/03/09 21:20:06 [INFO] source rdb[127.0.0.1:6379] checksum[yes]
2022/03/09 21:20:06 [WARN]
______________________________
\                             \           _         ______ |
 \                             \        /   \___-=O'/|O'/__|
  \   RedisShake, here we go !! \_______\          / | /    )
  /                             /        '/-==__ _/__|/__=-|  -GM
 /        Alibaba Cloud        /         *             \ | |
/                             /                        (o)
------------------------------
if you have any problem, please visit https://github.com/alibaba/RedisShake/wiki/FAQ

2022/03/09 21:20:06 [INFO] redis-shake configuration: {"ConfVersion":1,"Id":"redis-shake","LogFile":"","LogLevel":"info","SystemProfile":9310,"HttpProfile":9320,"Parallel":32,"SourceType":"standalone","SourceAddress":"127.0.0.1:6379","SourcePasswordRaw":"***","SourcePasswordEncoding":"***","SourceAuthType":"auth","SourceTLSEnable":false,"SourceRdbInput":[],"SourceRdbParallel":1,"SourceRdbSpecialCloud":"","TargetAddress":"127.0.0.1:6389","TargetPasswordRaw":"***","TargetPasswordEncoding":"***","TargetDBString":"3","TargetDBMapString":"","TargetAuthType":"auth","TargetType":"standalone","TargetTLSEnable":false,"TargetRdbOutput":"local_dump","TargetVersion":"6.2.6","FakeTime":"","KeyExists":"rewrite","FilterDBWhitelist":[],"FilterDBBlacklist":[],"FilterKeyWhitelist":[],"FilterKeyBlacklist":[],"FilterSlot":[],"FilterLua":false,"BigKeyThreshold":524288000,"Metric":true,"MetricPrintLog":false,"SenderSize":104857600,"SenderCount":4095,"SenderDelayChannelSize":65535,"KeepAlive":0,"PidPath":"","ScanKeyNumber":50,"ScanSpecialCloud":"","ScanKeyFile":"","Qps":200000,"ResumeFromBreakPoint":false,"Psync":true,"NCpu":0,"HeartbeatUrl":"","HeartbeatInterval":10,"HeartbeatExternal":"","HeartbeatNetworkInterface":"","ReplaceHashTag":false,"ExtraInfo":false,"SockFileName":"","SockFileSize":0,"FilterKey":null,"FilterDB":"","Rewrite":false,"SourceAddressList":["127.0.0.1:6379"],"TargetAddressList":["127.0.0.1:6389"],"SourceVersion":"6.2.6","HeartbeatIp":"127.0.0.1","ShiftTime":0,"TargetReplace":false,"TargetDB":3,"Version":"develop,cc226f841e2e244c48246ebfcfd5a50396b59710,go1.15.7,2021-09-03_10:06:55","Type":"sync","TargetDBMap":null}
2022/03/09 21:20:06 [INFO] DbSyncer[0] starts syncing data from 127.0.0.1:6379 to [127.0.0.1:6389] with http[9321], enableResumeFromBreakPoint[false], slot boundary[-1, -1]
2022/03/09 21:20:06 [INFO] input password is empty, skip auth address[127.0.0.1:6379] with type[auth].
2022/03/09 21:20:06 [INFO] DbSyncer[0] psync connect '127.0.0.1:6379' with auth type[auth] OK!
2022/03/09 21:20:06 [INFO] DbSyncer[0] psync send listening port[9320] OK!
2022/03/09 21:20:06 [INFO] DbSyncer[0] try to send 'psync' command: run-id[?], offset[-1]
2022/03/09 21:20:06 [INFO] Event:FullSyncStart  Id:redis-shake
2022/03/09 21:20:06 [INFO] DbSyncer[0] psync runid = 95203197147e62b36935e3b68a3f98e4c7fe99c2, offset = 0, fullsync
2022/03/09 21:20:06 [INFO] DbSyncer[0] +
2022/03/09 21:20:07 [INFO] DbSyncer[0] -
2022/03/09 21:20:07 [INFO] DbSyncer[0] +
2022/03/09 21:20:08 [INFO] DbSyncer[0] -

...
2022/03/09 21:21:31 [INFO] DbSyncer[0] total = 108.17MB -     102.68MB [ 94%]  entry=1064782
2022/03/09 21:21:32 [INFO] DbSyncer[0] total = 108.17MB -     104.14MB [ 96%]  entry=1079907
2022/03/09 21:21:33 [INFO] DbSyncer[0] total = 108.17MB -     105.57MB [ 97%]  entry=1094745
2022/03/09 21:21:34 [INFO] DbSyncer[0] total = 108.17MB -     106.89MB [ 98%]  entry=1108481
2022/03/09 21:21:35 [INFO] DbSyncer[0] total = 108.17MB -     108.17MB [100%]  entry=1122766
...

2022/03/09 21:21:33 [INFO] DbSyncer[0] total = 108.17MB -     105.57MB [ 97%]  entry=1094745
2022/03/09 21:21:34 [INFO] DbSyncer[0] total = 108.17MB -     106.89MB [ 98%]  entry=1108481
2022/03/09 21:21:35 [INFO] DbSyncer[0] total = 108.17MB -     108.17MB [100%]  entry=1122766
2022/03/09 21:21:35 [INFO] DbSyncer[0] sync rdb done
2022/03/09 21:21:35 [INFO] input password is empty, skip auth address[127.0.0.1:6389] with type[auth].
2022/03/09 21:21:35 [INFO] DbSyncer[0] FlushEvent:IncrSyncStart Id:redis-shake
2022/03/09 21:21:35 [INFO] input password is empty, skip auth address[127.0.0.1:6379] with type[auth].
2022/03/09 21:21:36 [INFO] DbSyncer[0] sync:  +forwardCommands=9      +filterCommands=0      +writeBytes=36

112만건 복제시 1분 20초가 소요됨.

복제가 끝나도 계속 연속해서 계속 sync 가 이어지며 (redis1 -> redis2) 당연히 redis1 에 값을 계속 밀어 넣어도 연속해서 sync 가 이어진다.

redis-shake 로 데이터 sync 중에 redis1 에 값 입력 시간 측정

2022-03-09 21:39:29.951538
113.0
114.0
115.0
116.0
117.0
118.0
119.0
120.0
121.0
122.0
2022-03-09 21:41:32.432655

10만건 입력시 1분 53초. rump 할 때 보다 약간 느리지만 같은 속도로 볼 수 있다. 이는 python 의 구현방법에 따라 차이가 있을 수 있겠지만..

redis-shake 가 답이다. alibaba 만세.

자세히 알아보지는 않았지만 rump 는 클라우드로 데이터를 넣는 용으로 쓸 수 있는 듯. 용도가 다른 듯.

minikube 로 기동한 kube cluster 왜 nodeport svc 에 접속되지 않을까? docker desktop kubenetes cluster support 를 쓰자.

Accessing apps | minikube (k8s.io)

minikube 에서 외부 접속 방법으로 정확히 설명 하고 있다.

k get svc -o wide 를 하면 보통 external IP 가 나오기 마련인데 (노드의)

나의 경우는 나오지 않았다. node 의 IP 를 알아야 nodeIP:nodePort 로 접속하는데..

nz@nzYoga7:/mnt/c/src/kubectl/ckad-test$ kubectl get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP        6d20h
nginx-deployment   ClusterIP   10.97.174.110   <none>        80/TCP         6d19h
nz-deployment      NodePort    10.107.63.94    <none>        80:31438/TCP   12m

minikube 가이드를 보니 명령을 쳐서 특정 서비스를 다시 찾아내야 하는 것 같다.

PS C:\Users\nzin4> minikube service nz-deployment
|-----------|---------------|-------------|---------------------------|
| NAMESPACE |     NAME      | TARGET PORT |            URL            |
|-----------|---------------|-------------|---------------------------|
| default   | nz-deployment |          80 | http://192.168.49.2:31438 |
|-----------|---------------|-------------|---------------------------|
🏃  Starting tunnel for service nz-deployment.
|-----------|---------------|-------------|------------------------|
| NAMESPACE |     NAME      | TARGET PORT |          URL           |
|-----------|---------------|-------------|------------------------|
| default   | nz-deployment |             | http://127.0.0.1:64489 |
|-----------|---------------|-------------|------------------------|
🎉  Opening service default/nz-deployment in default browser...

그럼 일단은 127.0.01: 에 새로 정의된 포트로는 접속이 가능하다.

windows 방화벽에 minikube 가 기동한 포트에 대해서 등록해 보았으나 minikube 는 설치된 docker 에 명령을 줄 뿐 실제로 minikube 가 연 포트에 대한 방화벽 설정은 무의미해 보인다.

docker desktop 에서 kubernetes 활성화

그냥 켜면 된다.

.kube/config 도 변경되는데 기본 context 가 활성화 되지 않는다.

kubectl config use-context docker-desktop

을 입력함으로서 .kube/config 에 이미 정의된 context 를 사용할 수 있게 된다.

minikube 안녕 즐거웠다.

docker desktop 은 nodeport 의 node IP 는 당연 node 그 자체인 localhost.

이제 node port 만 확인해서 오픈하면 된다.

PS C:\src\kubectl\ckad-test> kubectl.exe get svc -o wide
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP        4m49s   <none>
nz-deployment   NodePort    10.105.191.102   <none>        80:32116/TCP   8s      app=pod-nginx
PS C:\src\kubectl\ckad-test>

windows 에서 기동한 minikube cluster 를 wsl 에서 접근하기 위한 자동 설정 ~/.profile 수정

~/.profile 에 아래와 같은 복사 및 경로 구분자 변경하는 명령어를 넣으면 된다.

[USERID] 부분만 자신의 windows user id 로 치환하면 된다.

cp /mnt/c/Users/[USERID]/.kube/config ~/.kube/config #복사
sed -i 's/C:/\/mnt\/c/g' ~/.kube/config # c 드라이브 경로를 mnt로 치환
sed -i 's/\\/\//g' ~/.kube/config # \를 / 로 변환