반응형

 

OpenSearch Install, OpenSearch Dashboard install 및 Fluent-Bit 연동이다.

OpenSearch 설치시 바로 Helm으로 설치할 경우 패스워드가 없어서 에러가 발생할 뿐만아니라, 데모 인증서가

설치안되는 경우가 있다. 이 경우는 따로 패스워드 설정 및 데모인증서가아닌 인증서를 넣어주면되는데,

마지막에 따로 추가적으로 설정하는 방법을 정리한다.

 

Fluent-Bit 연동은 10번부터, 데모 인증서가 아닌 인증서 설정은 기타부분을 참조한다.

Fluent-Bit 연동을 위해 설치는 아래 링크 참조

2024.11.01 - [Develop/k8s] - k8s fluent-bit install and standard out test

 

0. 로깅 대상 Pod 관련

fluent-bit의 경우 Pod 내 label 이 app: 으로 시작하는 경우 로깅을 하지 못하므로,

반드시 label이 app: 으로 되어있는게 없도록 변경해주어야한다.

 

 

1. 메모리 맵 영역 조정

메모리 맵 영역을 조정하지 않으면 설치 후 에러가 발생함.

모든 서버에 적용.

$ vi /etc/sysctl.conf

# 해당 항목 추가 또는 수정
vm.max_map_count=262144

# 적용
$ sudo sysctl -p

 

 

2. OpenSearch 설치

helm chart로 설치할 예정이므로 아래 사이트에 접속해 helm charts를 다운받는다.

(가이드에 나온대로 바로 helm repo를 추가하여 설치 할 수 있지만, 위에 설명한대로 데모인증서가 설치안되는 경우가 있음.

데모인증서가 설치 안될 경우 아래 기타 항목 참조)

https://github.com/opensearch-project/helm-charts/releases

$ tar -zxvf opensearch-2.26.1.tgz
$ cd opensearch

 

 

3. values.yaml 내 OPENSEARCH_INITIAL_ADMIN_PASSWORD 설정 

ADMIN_PASSWORD를 설정한다. 해당 패스워드 설정하지 않을 경우 설치시 설정하라고 에러 발생

또한, 패스워드를 강하게 설정해야한다. 대문자, 숫자, 특수문자가 들어가야하며, 쉬운패스워드는 또 되지 않는다.

처음에 주석으로 되어있고 extraEnvs: [] 대괄호가 있으므로 대괄호는 반드시 지운다.

$ vi values.yaml
extraEnvs:
  - name: OPENSEARCH_INITIAL_ADMIN_PASSWORD
    value: wkyKr!2024

 

 

4. PV설정

기존 서버에 StorageClass가 설정되어있으면, 패스한다. 

StorageClass 가 없을 경우 PV를 설정해주어야한다. (PVC는 OpenSearch내에 적용되어 있음.)

모든 서버에 볼륨 폴더를 생성한다. (모든 서버에 할 필요는 없으나, 파드가 어디 서버에 동작될지 설정하지 않았으므로,

모든 폴더에 생성한다. 어디에 동작될지 설정할경우 해당 서버에만 폴더를 생성한다.)

 

opensearch가 statefulset으로 기본적으로 pod가 3개정도 동작하므로 pv를 미리 3개정도 만들어둔다.

아니면, helm install 후에 pvc와 pv 이름을 매칭하여 pv를 생성하고 pvc를 수정한다.

편한대로 진행하면됨.

# Worker Node가 2개뿐이라 2개씩 전부 생성
$ mkdir opensearch-pv
$ mkdir opensearch-pv2

 

pv 생성

$ vi pv-0.yaml
apiVersion: v1
metadata:
  name: opensearch-pv-0
  labels:
    service: opensearch-pv-0
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /root/opensearch-pv
 
$ vi pv-1.yaml
apiVersion: v1
metadata:
  name: opensearch-pv-1
  labels:
    service: opensearch-pv-1
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /root/opensearch-pv

$ vi pv-2.yaml
apiVersion: v1
metadata:
  name: opensearch-pv-2
  labels:
    service: opensearch-pv-2
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /root/opensearch-pv2
    
$ kubectl apply -f pv-0.yaml
$ kubectl apply -f pv-1.yaml
$ kubectl apply -f pv-2.yaml

 

 

5. helm install

3번의 values.yaml 수정하였으고 pv를 생성하였으면, 패키징 후 설치한다. (pv는 아래 먼저 실행 후 생성되는 것보고 맞춰서 생성해도 됨)

$ helm package .
$ helm install opensearch opensearch-2.26.1.tgz --create-namespace --namespace logging

# 실행확인
$ kubectl get pods -n logging
NAME                          READY   STATUS    RESTARTS   AGE
opensearch-cluster-master-0   1/1     Running   0          33m
opensearch-cluster-master-1   1/1     Running   0          33m
opensearch-cluster-master-2   1/1     Running   0          33m

 

 

6. 정상동작 확인

$ kubectl exec -it opensearch-cluster-master-0 -n logging -- /bin/bash
$  curl -XGET https://localhost:9200 -u 'admin:wkyKr!2024' --insecure
{
  "name" : "opensearch-cluster-master-0",
  "cluster_name" : "opensearch-cluster",
  "cluster_uuid" : "Iqk-kEIxRNWEvEXkCFX-BQ",
  "version" : {
    "distribution" : "opensearch",
    "number" : "2.17.1",
    "build_type" : "tar",
    "build_hash" : "1893d20797e30110e5877170e44d42275ce5951e",
    "build_date" : "2024-09-26T21:59:52.691008096Z",
    "build_snapshot" : false,
    "lucene_version" : "9.11.1",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

 

 

7. OpenSearch DashBoard 설치

OpenSeach와 마찬가지로 helm chart로 설치할 예정이므로 아래 사이트에 접속해 helm charts를 다운받는다.

https://github.com/opensearch-project/helm-charts/releases

 

다운 받았으면, 바로 실행한다.

$ helm install opensearch-dashboards opensearch-dashboards-2.24.1.tgz --create-namespace --namespace logging

# 실행 후 확인
$ kubectl get pods -n logging
NAME                                     READY   STATUS    RESTARTS   AGE
opensearch-dashboards-649d556895-r4vwn   1/1     Running   0          2m13s

 

 

8. OpenSearch DashBoard 접근을 위한 ingress 설정

$ vi ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: opensearch-dashboard
  namespace: logging
spec:
  ingressClassName: nginx
  rules:
  - host: os-dashboard.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: opensearch-dashboards
            port:
              number: 5601
              
 $ kubectl apply -f ingress.yaml

 

 

9. 접속 확인

계정은 admin

패스워드는 3번에 설정한 패스워드 입력

 

 

10. Fluent-Bit 연동

먼저 Fluent-Bit 이 설치되어 있어야 한다. 설치방법은 아래 링크 참조

2024.11.01 - [Develop/k8s] - k8s fluent-bit install and standard out test

(위 링크에 따라 그대로 설정했으면 stdout 부분은 제거한다.)

OUTPUT 옵션은 필요에 따라 가이드보고 적용하며,

Host는 oepnsearch가 statefulset으로 동작하므로 opensearch service의 headless service로 연결한다.

$ kubectl edit cm fluent-bit
# [OUTPUT] 에 stdout이 있으면 해당 부분 제거 후 아래 부분 추가

   [OUTPUT]
        Name opensearch
        Match kube.*
        Host opensearch-cluster-master-headless.logging
        Port 9200
        tls On
        tls.verify Off
        HTTP_User admin
        HTTP_Passwd wkyKr!2024
        Retry_Limit False
        Suppress_Type_Name On

 

fluent-bit 의 config map hot reload 를 설정하지 않았으므로, fluent-bit pod를 전체 재기동한다.

 

11. 연동 후 OpenSearch에서 확인을 위해 서비스를 통한 로깅 테스트 후 Fluent-Bit 확인

2024.11.01 - [Develop/k8s] - k8s fluent-bit install and standard out test

해당 글에서 생성한 서비스의 로그가 잘 표시되는 것을 확인

 

 

기타. 데모인증서가 아닌 인증서 설정

helm 내의 values.yaml 를 수정하지 않고 바로 공식 가이드 대로 배포할 경우 패스워드도 없고 데모 인증서가 생성 되지 않을 경우가 있는데,

패스워드를 설정하고 인증서 생성 후 인증서는 pv에 넣어주면 된다.

 

1. 패스워드 설정

패스워드 설정은 statefulset의 환경변수에 입력해주면된다.

$ kubectl edit sts -n logging opensearch-cluster-master
...
containers:
      - env:
        - name: OPENSEARCH_INITIAL_ADMIN_PASSWORD
          value: wkyKr!2024
...

 

 

2. PV는 있다고 가정 후 인증서 생성 (없을 경우 위 내용 중 4번 확인)

$ openssl genrsa -out root-ca-key.pem 2048
$ openssl req -new -x509 -sha256 -key root-ca-key.pem -out root-ca.pem -days 730
$ openssl genrsa -out esnode-key-temp.pem 2048
$ openssl pkcs8 -inform PEM -outform PEM -in esnode-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out esnode-key.pem
$ openssl req -new -key esnode-key.pem -out esnode.csr
$ openssl x509 -req -in esnode.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out esnode.pem -days 730

 

 

3. 생성한 인증서 중 esnode.pem, esnode-key.pem, root-ca.pem 을 pv 폴더에 이동

OpenSearch pod 와 pv 간 mountPath가 안맞는 경우가 있어 statefulset 내 mountPath수정함.

또한 위 4번에서 생성한 opensearch-pv, opensearch-pv2 폴더내 config 폴더 생성

esnode.pem, esnode-key.pem, root-ca.pem 를 config 폴더에 이동

$ kubectl get sts -n logging opensearch-cluster-master -o yaml

# 수정 전
- mountPath: /usr/share/opensearch/config/opensearch.yml
  name: config-emptydir
  
# 수정 후
- mountPath: /usr/share/opensearch/data/config/opensearch.yml
  name: config-emptydir
  
$ mkdir ~/opensearch-pv/config
$ mkdir ~/opensearch-pv2/config

esnode.pem, esnode-key.pem, root-ca.pem 해당폴더로 복사한다

 

4. config map 수정

  allow_unsafe_democertificates: true -> false로 수정

$ kubectl edit cm -n logging opensearch-cluster-master-config -o yaml

# 기존에 true로 되어있음 false로 수정
allow_unsafe_democertificates: false

 

 

참고 :

https://opensearch.org/docs/latest/install-and-configure/install-opensearch/index/

https://opensearch.org/docs/latest/install-and-configure/install-opensearch/helm/

https://opensearch.org/docs/latest/install-and-configure/install-dashboards/helm/

https://opensearch.org/docs/latest/security/configuration/generate-certificates/

https://docs.fluentbit.io/manual/pipeline/outputs/opensearch

 

반응형
반응형

 

k8s에서 fluent-bit 설치 및 stdout 테스트이다. opensearch 설치 및 연동테스트는 아래 링크참조

2024.11.03 - [Develop/k8s] - OpenSearch, Dashboard 설치 및 Fluent-Bit OpenSeach 연동

 

 

0. 로깅 대상 Pod 관련

fluent-bit의 경우 Pod 내 label 이 app: 으로 시작하는 경우 로깅을 하지 못하므로,

반드시 label이 app: 으로 되어있는게 없도록 변경해주어야한다.

 

 

1. 우선 테스트할 서비스를 하나 생성한다

nodejs로 로깅 테스트 - https://github.com/wonkwangyeon/stdout-nodejs

java서비스로 로깅 테스트 - https://github.com/wonkwangyeon/stdout-java

 

 

2. 테스트 서버를 배포한다.

$ kubectl apply -f k8s.yaml
deployment.apps/stdout-node created
service/stdout-node-service created
ingress.networking.k8s.io/stdout-node-ingress created

$ kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
stdout-node-6f945d7989-6xjp2   1/1     Running   0          20s

 

 

3. fluent-bit install

$ helm repo add fluent https://fluent.github.io/helm-charts
$ helm upgrade --install fluent-bit fluent/fluent-bit

# namespace 를 주지않으면 default namespace에 생성된다
$ kubectl get pods
NAME                           READY   STATUS              RESTARTS   AGE
fluent-bit-67blm               0/1     ContainerCreating   0          5s
fluent-bit-vvt7c               0/1     ContainerCreating   0          5s

 

 

4. 현재 elasticsearch 나 opensearch 를 설치하지 않았으므로 stdout테스트를 진행한다. (테스트 후 opensearch 설치 예정)

기존에 있던 OUTPUT인 elasticsearch를 삭제하고 [OUTPUT]으로 stdout 을 추가한다.

(해당 Name의 경우 이름이 정해져있으며, 이름마다 사용할 수 있는 변수?가 다르다. 공식 가이드에서 확인 가능하다.)

$ kubectl edit cm fluent-bit

	기존에 있던 elasticsearch OUTPUT 삭제
    [OUTPUT]
        Name es
        Match host.*
        Host elasticsearch-master
        Logstash_Format On
        Logstash_Prefix node
        Retry_Limit False
        
    아래 stdout OUTPUT 추가
    [OUTPUT]
        Name stdout
        Match kube.*

# config map 수정 후 fluent-bit pod 삭제를 통해 재기동한다.
$ kubectl delete pods fluent-bit-67blm  fluent-bit-vvt7c
pod "fluent-bit-67blm" deleted
pod "fluent-bit-vvt7c" deleted

 

 

5. 1번에서 설치한 테스트 pod 위치를 확인 후 같은 위치의 fluent-bit pod 의 로그를 f option을 통해 확인한다.

이후 테스트 서비스를 호출하여 로그가 fluent-bit pod에 출력되는지 확인한다.

(OpenSearch 연동은 아래링크 참조 :

2024.11.03 - [Develop/k8s] - OpenSearch, Dashboard 설치 및 Fluent-Bit OpenSeach 연동)

# 테스트 서비스 위치 확인 (2번에 있는 것 확인)
$ kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE     IP          NODE      NOMINATED NODE   READINESS GATES
stdout-node-6f945d7989-6xjp2   1/1     Running   0          27m     10.0.2.9    worker2   <none>           <none>

# fluent-bit 위치 확인 (2번 fluent-bit pod 확인)
$ kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE     IP          NODE      NOMINATED NODE   READINESS GATES
fluent-bit-bng54               1/1     Running   0          6m41s   10.0.0.62   worker1   <none>           <none>
fluent-bit-crjlm               1/1     Running   0          6m40s   10.0.2.37   worker2   <none>           <none>

# 2번 fluent-bit 로그 출력
$ kubectl logs -f fluent-bit-crjlm  

# service 호출 후 아래 로그 확인
[0] kube.var.log.containers.stdout-node-6f945d7989-6xjp2_default_stdout-a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10.log: [[1730388117.989743401, {}], {"time"=>"2024-10-31T15:21:57.989743401Z", "stream"=>"stdout", "_p"=>"F", "log"=>"2024-10-31T15:21:57.989Z debug : Log Hello World", "kubernetes"=>{"pod_name"=>"stdout-node-6f945d7989-6xjp2", "namespace_name"=>"default", "pod_id"=>"037e0276-650f-460f-85cb-095ed4f65cd7", "labels"=>{"pod-template-hash"=>"6f945d7989", "stdout"=>"stdout-node"}, "host"=>"worker2", "container_name"=>"stdout", "docker_id"=>"a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10", "container_hash"=>"sha256:aff389fbc4cac45f0ca6de06328e7d51f1d887306a9c278d4349f61e281ac562", "container_image"=>"docker.io/stdout/node:latest"}}]
[1] kube.var.log.containers.stdout-node-6f945d7989-6xjp2_default_stdout-a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10.log: [[1730388117.989830525, {}], {"time"=>"2024-10-31T15:21:57.989830525Z", "stream"=>"stdout", "_p"=>"F", "log"=>"2024-10-31T15:21:57.989Z info : Log Hello World", "kubernetes"=>{"pod_name"=>"stdout-node-6f945d7989-6xjp2", "namespace_name"=>"default", "pod_id"=>"037e0276-650f-460f-85cb-095ed4f65cd7", "labels"=>{"pod-template-hash"=>"6f945d7989", "stdout"=>"stdout-node"}, "host"=>"worker2", "container_name"=>"stdout", "docker_id"=>"a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10", "container_hash"=>"sha256:aff389fbc4cac45f0ca6de06328e7d51f1d887306a9c278d4349f61e281ac562", "container_image"=>"docker.io/stdout/node:latest"}}]
[2] kube.var.log.containers.stdout-node-6f945d7989-6xjp2_default_stdout-a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10.log: [[1730388117.989854900, {}], {"time"=>"2024-10-31T15:21:57.9898549Z", "stream"=>"stdout", "_p"=>"F", "log"=>"2024-10-31T15:21:57.989Z warn : Log Hello World", "kubernetes"=>{"pod_name"=>"stdout-node-6f945d7989-6xjp2", "namespace_name"=>"default", "pod_id"=>"037e0276-650f-460f-85cb-095ed4f65cd7", "labels"=>{"pod-template-hash"=>"6f945d7989", "stdout"=>"stdout-node"}, "host"=>"worker2", "container_name"=>"stdout", "docker_id"=>"a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10", "container_hash"=>"sha256:aff389fbc4cac45f0ca6de06328e7d51f1d887306a9c278d4349f61e281ac562", "container_image"=>"docker.io/stdout/node:latest"}}]
[3] kube.var.log.containers.stdout-node-6f945d7989-6xjp2_default_stdout-a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10.log: [[1730388117.989863650, {}], {"time"=>"2024-10-31T15:21:57.98986365Z", "stream"=>"stdout", "_p"=>"F", "log"=>"2024-10-31T15:21:57.989Z error : Log Hello World", "kubernetes"=>{"pod_name"=>"stdout-node-6f945d7989-6xjp2", "namespace_name"=>"default", "pod_id"=>"037e0276-650f-460f-85cb-095ed4f65cd7", "labels"=>{"pod-template-hash"=>"6f945d7989", "stdout"=>"stdout-node"}, "host"=>"worker2", "container_name"=>"stdout", "docker_id"=>"a9b9155dd52d8338234bbbf37ccc057d72d7d4731044068a9beaaa2aeeba4f10", "container_hash"=>"sha256:aff389fbc4cac45f0ca6de06328e7d51f1d887306a9c278d4349f61e281ac562", "container_image"=>"docker.io/stdout/node:latest"}}]

 

 

fluent-bit를 설치하고 간단히 stdout 을 통해 테스트가 되는 것을 확인하였다.

OpenSearch 연동은 아래 링크 참조

2024.11.03 - [Develop/k8s] - OpenSearch, Dashboard 설치 및 Fluent-Bit OpenSeach 연동

반응형
반응형

 

kubernetes-dashboard 는 기본적으로 localhost 에서 https 를 권장하지만 Ingress 를 적용하여 접속할 수도 있다.

kubernetes-dashboard-kong-proxy를 기준으로 https ingress 접속하는 방법이다.

 

 

1. 인증서 생성

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=dashboard.wky.kr/O=Kubernetes"
또는
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=dashboard.wky.kr/O=Kubernetes" -addext "subjectAltName = DNS:dashboard.wky.kr"

 

 

2. secret 생성

kubectl create secret tls tls-dashboard --key tls.key --cert tls.crt -n kubernetes-dashboard

 

 

3. Ingress 생성 및 적용

# vi ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
  ingressClassName: nginx
  rules:
  - host: dashboard.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-kong-proxy
            port:
              number: 443
  tls:
  - hosts:
    - dashboard.wky.kr
    secretName: tls-dashboard
 
 # 적용
 kubectl apply -f ingress.yaml -n kubernetes-dashboard

 

 

4. 접속할 pc 의 hosts에 등록

vi /etc/hosts

172.1.1.1 dashboard.wky.kr

 

 

5. 확인

 

 

기타. ssl-passthrough

ssl-passthrough 를 적용하기 위해선 deployment에 --enable-ssl-passthrough 플래그를 추가한다.

kubectl edit deploy -n ingress-nginx ingress-nginx-controller

...
spec:
  containers:
  - args:
    - /nginx-ingress-controller
    - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
    - --election-id=ingress-nginx-leader
    - --controller-class=k8s.io/ingress-nginx
    - --ingress-class=nginx
    - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
    - --validating-webhook=:8443
    - --validating-webhook-certificate=/usr/local/certificates/cert
    - --validating-webhook-key=/usr/local/certificates/key
    - --enable-ssl-passthrough=true
...

 

ingress 설정

# vi ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /dash(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: kubernetes-dashboard-kong-proxy
            port:
              number: 443
 
 # 적용
 kubectl apply -f ingress.yaml -n kubernetes-dashboard

 

확인

반응형
반응형

 

k8s 인증서가 갱신되더라도 전에 사용하고 있던 config파일 내에 client-certificate-data 항목이 만료가 되지 않았으면,

그대로 정상동작하며, 해당 데이터에 대한 만료일자를 확인하는 방법이다.

 

root@master:~/tmp $ cat ~/.kube/config # client-certificate-data 값 확인
root@master:~/tmp $ echo "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tL~~~~~" | base64 --decode > client.crt
root@master:~/tmp $ ls
client.crt
root@master:~/tmp $ openssl x509 -in client.crt -noout -enddate
notAfter=Apr  7 13:49:20 2025 GMT

 

 

반응형
반응형

 

serviceAccount 를 현재 사용하고 있는 pod 들을 조회하기 위해서는 --field-selector 옵션을 통해 조회 가능하다.

$ kubectl get pods -n kube-system --field-selector spec.serviceAccountName=cilium -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
cilium-2nrnz   1/1     Running   0          13m   172.16.1.1   worker1   <none>           <none>
cilium-ldsn5   1/1     Running   0          13m   172.16.1.2   worker2   <none>           <none>
cilium-pcm6x   1/1     Running   0          13m   172.16.1.3   master    <none>           <none>

 

serviceAccount 뿐만아니라 여러 field 선택을 통해 다른것들도 조회가능하다.

https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/field-selectors/

 

필드 셀렉터

필드 셀렉터 는 한 개 이상의 리소스 필드 값에 따라 쿠버네티스 리소스를 선택하기 위해 사용된다. 필드 셀렉터 쿼리의 예시는 다음과 같다. metadata.name=my-service metadata.namespace!=default status.phase=Pe

kubernetes.io

 

반응형
반응형

 

k8s cluster scale out 시 kubeadm token이 필요하다.

kubeadm token의 경우 만료일자가 있어 어느정도 기한이 지나면 사라지기 때문에 재생성이 필요하다.

방법이 2개 정도 있으며, 생성 후 사용하는 법과 생성과 동시에 명령어를 생성하는 법이 있다.

 

1. 기존 토큰이 있을 경우 kubeadm token list 명령어를 통해 token 조회 가능

kubeadm token list​

 

기존 토큰을 사용하거나 토큰이 없어서 재생성 후 사용할 경우 기존 토큰이 없을 경우는 토큰 생성

kubeadm token create

root@master:~# kubeadm token create
ck9j53.uiwl5qd5s9vwdevzv

 

 

discovery-token-ca-cert-hash 조회

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

root@master:~# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
c8158df76056620db625ba08a4faaf47f795e4bf0517d6a296657dc6f59192e3

 

 

조회 후 kubeadm join 옵션을 통해 신규 Node 추가

kubeadm join 127.0.0.1:6443 --token ck9j53.uiwl5qd5s9vwdevzv \
--discovery-token-ca-cert-hash sha256:c8158df76056620db625ba08a4faaf47f795e4bf0517d6a296657dc6f59192e3

 

 

2. --print-join-command 로 바로 출력

kubeadm token create --print-join-command

root@master:~# kubeadm token create --print-join-command
kubeadm join 127.0.0.1:6443 --token ae46ls.ggne5zqvxtyv2153 --discovery-token-ca-cert-hash sha256:c8158df76056620db625ba08y4fabf37f715e4af0517d6x296657dc6f59194e2

 

반응형
반응형

 

서버 작업 중 kubelet.service 재기동시 계속 종료되는 현상이 발생되어 journalctl -xeu kubelet를 통해 로그를 확인하였으나, 그 당시 엄청 많은 쓸데없는 에러로 인해서 해당 문제를 해결하는데 시간을 많이 허비 하였다.

(로그찾을때 E(Error) 만 보느라 F(Fatal)을 놓쳤었음.)

 

아래 에러로 인하여 kubelet이 재기동 되지 않은 것을 확인하였으며, kenel panic을 재조정하여 해결하였다.

Failed to start ContainerManager invalid kernel flag: kenrnel/panic, expected valued: 10, actual value :0

 

이 문제는 kubeadm으로 k8s 설치시 발생하진 않지만, kubespray로 k8s를 설치하게되면,  기본적으로 kernel.panic=10으로 들어가게된다.

해당 옵션은 kubelet 기동 인자 전달시 예상한값과 다를 경우 패스하거나 실패 시키는 옵션인데, 누군가 kernel.panic=0 으로 변경하여 에러가 발생하였다.

 

조치방법은 /etc/sysctl.conf 내 kernel.panic 옵션의 값을 변경하면된다.

# vi /etc/sysctl.conf
kernel.panic=10

 

 

기타.

kubespray로 k8s를 설치할 경우 kubelet service파일(/etc/systemd/system/kubelet.service)에 인자들이 들어간다.

적용된 kernel.panic 옵션을 통해 해당 인자들이 탐지되어 정상기동하거나 실패하는 듯 하다.

# cat /etc/systemd/system/kubelet.service

[Service]
EnvironmentFile=-/etc/kubernetes/kubelet.env
ExecStart=/usr/local/bin/kubelet \
                $KUBE_LOGTOSTDERR \
                $KUBE_LOG_LEVEL \
                $KUBELET_API_SERVER \
                $KUBELET_ADDRESS \
                $KUBELET_PORT \
                $KUBELET_HOSTNAME \
                $KUBELET_ARGS \
                $DOCKER_SOCKET

 

반응형
반응형

 

해당 가이드는 지속적으로 수정 예정. 동작 및 코드 문의시 댓글 부탁드립니다.

 

k8s 를 이용하다보면 Node들에 container image들이 쌓이게 되는데 이를 정리하는 CronJob 이다

CronJob에 이용되는 image는 아래 dokcer hub에서 확인 할 수 있다.(amd64, arm64 아키텍쳐 사용가능)

https://hub.docker.com/r/pangyeons/image-prune

 

https://hub.docker.com/r/pangyeons/image-prune

 

hub.docker.com

 

현재버전 - 1.2

 

기능은 옵션을 통해 docker 뿐만아니라 crictl 명령어를 이용하여 image pruning 을 진행할 수 있으며,

Control Plane 도 정리할지 안할지 옵션을 통해 선택할 수 있다.

 

사용방법은 아래와 같다.

 

1. 아래는 기본적인 yaml 파일이며 command 배열과 mountPath, API_TOKEN, API_URL, KEY_NAME, defaultMode는 필수 옵션이다.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: image-prune
spec:
  schedule: "0 0 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: image-prune
            image: pangyeons/image-prune:latest
            imagePullPolicy: IfNotPresent
            command: # 아래 command 배열 수정 및 삭제 금지
            - /bin/sh
            - -c
            - chmod +x image_prune.sh; /image_prune.sh
            volumeMounts:
            - mountPath: /etc/sshkey # 수정 및 삭제 금지
              name: secret-sshkey
            env:
            - name: API_TOKEN # 수정 및 삭제 금지
              valueFrom:
                secretKeyRef:
                  key:
                  name: 
            - name: API_URL # 수정 및 삭제 금지
              value: ""
            - name: KEY_NAME # 수정 및 삭제 금지
              value: ""
            - name: CRI_TYPE
              value: ""
            - name: CONTROL_PLANE
              value: ""
            - name: OS_USER
              value: ""
            - name: PORT
              value: "6443"
            - name: LOG_FILE
              value: ""
          restartPolicy: OnFailure
          volumes:
          - name: secret-sshkey
            secret:
              defaultMode: 0600 # 수정 및 삭제 금지
              secretName:

 

2. ssh key 생성 및 등록

ssh-keygen 을 통해 ssh key 생성

ssh-keygen -t rsa # ex) id_rsa, id_rsa.pub 생성

 

 

생성 후 나온 public key 모든 node에 등록

# id_rsa.pub 등록
vi ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNbPyWARlsD1OmjgHcQAewXvmTbAJYAYMlRgjgUKu69uVyKB8ZS0n3KuLJy9JoTF4y/VOL5DTCU2TFb1A1eIhM4Ox5sPoNTWIG7h/crH

 

생성한 ssh private key를 k8s secret에 등록

kubectl create secret generic sshkey --from-file=privatekey=./id_rsa

 

 

3. k8s API를 사용할 API Token 생성(현재 Ready 중인 Node 및 Master/Worker Node 구분을 위함)

API Token 생성을 위한 Serivce Account 생성 및 API 조회에 필요한 Role 부여

vi test-token.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-token
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-nodes
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-nodes-binding
subjects:
- kind: ServiceAccount
  name: test-token
  namespace: default
roleRef:
  kind: ClusterRole
  name: read-nodes
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: test-token-secret
  namespace: default
  annotations:
    kubernetes.io/service-account.name: test-token

 

 

생성한 계정에 대한 API Token 조회

API_TOKEN=$(kubectl get secret test-token-secret -o jsonpath="{.data.token}" | base64 --decode)

 

4. 생성한 API Token을 k8s secret 으로 생성

kubectl create secret generic apitoken --from-literal=apitoken=$API_TOKEN

 

5. CronJob 생성

API_TOKEN secret으로 생성한 apitoken key: apitoken
name: apitoken
필수
API_URL Control Plane API URL 127.0.0.1 필수
KEY_NAME secret으로 생성한 ssh key privatekey 필수
OS_USER Node들에 접속할 OS계정 user 기본값 : root
CRI_TYPE 컨테이너 런타임 인터페이스 docker/crictl 기본값 : root
CONTROL_PLANE CONTROL PLANE 도 정리 true/false 기본값 : true
PORT k8s API PORT 6443 기본값 : 6443
LOG_FILE 삭제로그 파일로 저장
/var/log/image-prune_yyyymmddhhMM.log
true/false 기본값 : false

 

apiVersion: batch/v1
kind: CronJob
metadata:
  name: image-prune
spec:
  schedule: "0 0 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: image-prune
            image: pangyeons/image-prune:latest
            imagePullPolicy: IfNotPresent
            command: # 아래 command 배열 수정 및 삭제 금지
            - /bin/sh
            - -c
            - chmod +x image_prune.sh; /image_prune.sh
            volumeMounts:
            - mountPath: /etc/sshkey # 수정 및 삭제 금지
              name: secret-sshkey
            env:
            - name: API_TOKEN # 수정 및 삭제 금지
              valueFrom:
                secretKeyRef:
                  key: apitoken # 위에 가이드대로 생성한 token
                  name: apitoken # 위에 가이드대로 생성한 token
            - name: API_URL # 수정 및 삭제 금지
              value: "172.1.1.1" # Control Plane API IP
            - name: KEY_NAME # 위에 가이드대로 생성한 SSH KEY Secret
              value: "privatekey"
            - name: CRI_TYPE # Container Runtime이 crictl일 경우
              value: "crictl"
            - name: CONTROL_PLANE # Control Plane에서는 동작안함.
              value: "false"
            - name: PORT
              value "6443"
            - name: LOG_FILE
              value: "false"
          restartPolicy: OnFailure
          volumes:
          - name: secret-sshkey
            secret:
              defaultMode: 0600 # 수정 및 삭제 금지
              secretName: sshkey # 위에 가이드대로 생성한 SSH KEY Secret

 

반응형
반응형

 

shell script 작성 후 shell script를 실행 시키는 image 를 Alpine linux 로 이미지 생성 후 Pod 실행시

No such file or directory 에러가 발생하였다.

 

확인해보니 shell script 제일 상단에 #!/bin/bash 가 문제였고

Alpine linux 의 경우 shell script 제일 상단에 #!/bin/sh 로 해주어야한다.

#!/bin/bash -> #!bin/sh

 

bash를 사용해야하는 경우라면 bash를 추가해서 사용하면 된다.

apk add bash

 

반응형
반응형

 

crio 설치시 service start가 안되고 아래와 같은 에러가 발생하였다.

validating runtime config: cannot enable checkpoint/restore support without the criu binary in $PATH

 

간단히 criu만 설치해주면 되었는데, apt list를 조회하니 아래와 같이 2개가 조회되었다.

criu/jammy 3.16.1-2 arm64

golang-github-checkpoint-restore-go-criu-dev/jammy 5.1.0-1 all

 

그래서 2개다 설치해주었다. (하나만 설치해도 됐을지도)

apt-get install criu/jammy
apt-get install golang-github-checkpoint-restore-go-criu-dev/jammy

# 설치 후 cri-o 재시작
systemctl restart crio.service

 

 

반응형

+ Recent posts