반응형

 

 

이러다 설치만 장인되겠다

해당 글은 helm chart로 설치하는 정리 가이드이다.

가이드 작성시 상세 설명은 따로 하지 않는다. 

 

OpenSearch Operator로 설치는 가이드보면 설치자체는 어려운것은 없으나, 인증서 부분에서 상당히 복잡하기 때문에 아래 글 참고한다.

2024.11.28 - [Develop/OpenSearch / FluentBit] - OpenSearch Operator Certificate 설정

 

Single Node 로 설치는 아래 글 참고한다.

2025.03.06 - [Develop/OpenSearch / FluentBit] - OpenSearch SingleNode

 

OpenSearch FluentBit 연동은 아래 글 참고한다.

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

 

OpenSearch Operator Coordinator 설치는 아래 글 참고한다.

2025.02.18 - [Develop/OpenSearch / FluentBit] - OpenSearch Operator Coordinator

 

 

1. Demo 인증서가아닌 self 인증서를 생성한다. 인증서가 있으면 건너 뛴다.

# root ca 생성
openssl genrsa -out root-ca-key.pem 2048
openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/CN=opensearch" -out root-ca.pem -days 3650

# OpenSearch Operator가 OpenSearch Cluster를 관리하는 관리자 인증서
openssl genrsa -out admin-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
openssl req -new -key admin-key.pem -subj "/CN=opensearch-admin" -out admin.csr
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 3650

# Node간 DNS 통신을 위해 subjectAltName 생성
echo 'subjectAltName=DNS:opensearch-cluster-master,DNS:opensearch-cluster-master.logging,DNS:opensearch-cluster-master.logging.svc,DNS:opensearch-cluster-master.logging.svc.cluster.local' > san.ext

# OpenSearch Node간 인증서
openssl genrsa -out node-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node-key.pem
openssl req -new -key node-key.pem -subj "/CN=opensearch-cluster-master" -out node.csr
openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node.pem -days 3650 -extfile san.ext

# OpenSearch yaml에 등록할 인증서 파일들 secret으로 생성
kubectl create ns logging
kubectl create secret generic opensearch-cert --from-file=root-ca.pem=root-ca.pem --from-file=admin.pem=admin.pem --from-file=admin-key.pem=admin-key.pem \
--from-file=root-ca.pem=root-ca.pem --from-file=node.pem=node.pem --from-file=node-key.pem=node-key.pem -n logging

 

 

2. helm repo 추가

공식 가이드에 나온대로 진행한다.

helm repo add opensearch https://opensearch-project.github.io/helm-charts
helm repo upadte

 

 

3. OpenSearch에 사용할 관리자 계정 secret 생성

아래 링크에서 가져온 샘플이다. 필요에 따라 수정해서 사용하면 됨.

https://github.com/opensearch-project/opensearch-k8s-operator/blob/main/opensearch-operator/examples/securityconfig-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: securityconfig-secret
type: Opaque
stringData:
      action_groups.yml: |-
         _meta:
           type: "actiongroups"
           config_version: 2
      internal_users.yml: |-
        _meta:
          type: "internalusers"
          config_version: 2
        admin:
          hash: "$2y$12$lJsHWchewGVcGlYgE3js/O4bkTZynETyXChAITarCHLz8cuaueIyq"
          reserved: true
          backend_roles:
          - "admin"
          description: "admin user"
        dashboarduser:
          hash: "$2a$12$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H."
          reserved: true
          description: "OpenSearch Dashboards user"
      nodes_dn.yml: |-
        _meta:
          type: "nodesdn"
          config_version: 2
      whitelist.yml: |-
        _meta:
          type: "whitelist"
          config_version: 2
      tenants.yml: |-
        _meta:
          type: "tenants"
          config_version: 2
      roles_mapping.yml: |-
        _meta:
          type: "rolesmapping"
          config_version: 2
        all_access:
          reserved: false
          backend_roles:
          - "admin"
          description: "Maps admin to all_access"
        own_index:
          reserved: false
          users:
          - "*"
          description: "Allow full access to an index named like the username"
        readall:
          reserved: false
          backend_roles:
          - "readall"
        manage_snapshots:
          reserved: false
          backend_roles:
          - "snapshotrestore"
        dashboard_server:
          reserved: true
          users:
          - "dashboarduser"
      roles.yml: |-
        _meta:
          type: "roles"
          config_version: 2
        dashboard_read_only:
          reserved: true
        security_rest_api_access:
          reserved: true
        # Allows users to view monitors, destinations and alerts
        alerting_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/alerting/alerts/get'
            - 'cluster:admin/opendistro/alerting/destination/get'
            - 'cluster:admin/opendistro/alerting/monitor/get'
            - 'cluster:admin/opendistro/alerting/monitor/search'
        # Allows users to view and acknowledge alerts
        alerting_ack_alerts:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/alerting/alerts/*'
        # Allows users to use all alerting functionality
        alerting_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster_monitor'
            - 'cluster:admin/opendistro/alerting/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices_monitor'
                - 'indices:admin/aliases/get'
                - 'indices:admin/mappings/get'
        # Allow users to read Anomaly Detection detectors and results
        anomaly_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/ad/detector/info'
            - 'cluster:admin/opendistro/ad/detector/search'
            - 'cluster:admin/opendistro/ad/detectors/get'
            - 'cluster:admin/opendistro/ad/result/search'
            - 'cluster:admin/opendistro/ad/tasks/search'
            - 'cluster:admin/opendistro/ad/detector/validate'
            - 'cluster:admin/opendistro/ad/result/topAnomalies'
        # Allows users to use all Anomaly Detection functionality
        anomaly_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster_monitor'
            - 'cluster:admin/opendistro/ad/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices_monitor'
                - 'indices:admin/aliases/get'
                - 'indices:admin/mappings/get'
        # Allows users to read Notebooks
        notebooks_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/notebooks/list'
            - 'cluster:admin/opendistro/notebooks/get'
        # Allows users to all Notebooks functionality
        notebooks_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/notebooks/create'
            - 'cluster:admin/opendistro/notebooks/update'
            - 'cluster:admin/opendistro/notebooks/delete'
            - 'cluster:admin/opendistro/notebooks/get'
            - 'cluster:admin/opendistro/notebooks/list'
        # Allows users to read observability objects
        observability_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opensearch/observability/get'
        # Allows users to all Observability functionality
        observability_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opensearch/observability/create'
            - 'cluster:admin/opensearch/observability/update'
            - 'cluster:admin/opensearch/observability/delete'
            - 'cluster:admin/opensearch/observability/get'
        # Allows users to read and download Reports
        reports_instances_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to read and download Reports and Report-definitions
        reports_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/definition/get'
            - 'cluster:admin/opendistro/reports/definition/list'
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to all Reports functionality
        reports_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/definition/create'
            - 'cluster:admin/opendistro/reports/definition/update'
            - 'cluster:admin/opendistro/reports/definition/on_demand'
            - 'cluster:admin/opendistro/reports/definition/delete'
            - 'cluster:admin/opendistro/reports/definition/get'
            - 'cluster:admin/opendistro/reports/definition/list'
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to use all asynchronous-search functionality
        asynchronous_search_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/asynchronous_search/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices:data/read/search*'
        # Allows users to read stored asynchronous-search results
        asynchronous_search_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/asynchronous_search/get'
        # Allows user to use all index_management actions - ism policies, rollups, transforms
        index_management_full_access:
          reserved: true
          cluster_permissions:
            - "cluster:admin/opendistro/ism/*"
            - "cluster:admin/opendistro/rollup/*"
            - "cluster:admin/opendistro/transform/*"
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices:admin/opensearch/ism/*'
        # Allows users to use all cross cluster replication functionality at leader cluster
        cross_cluster_replication_leader_full_access:
          reserved: true
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - "indices:admin/plugins/replication/index/setup/validate"
                - "indices:data/read/plugins/replication/changes"
                - "indices:data/read/plugins/replication/file_chunk"
        # Allows users to use all cross cluster replication functionality at follower cluster
        cross_cluster_replication_follower_full_access:
          reserved: true
          cluster_permissions:
            - "cluster:admin/plugins/replication/autofollow/update"
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - "indices:admin/plugins/replication/index/setup/validate"
                - "indices:data/write/plugins/replication/changes"
                - "indices:admin/plugins/replication/index/start"
                - "indices:admin/plugins/replication/index/pause"
                - "indices:admin/plugins/replication/index/resume"
                - "indices:admin/plugins/replication/index/stop"
                - "indices:admin/plugins/replication/index/update"
                - "indices:admin/plugins/replication/index/status_check"
      config.yml: |-
        _meta:
          type: "config"
          config_version: "2"
        config:
          dynamic:
            http:
              anonymous_auth_enabled: false
            authc:
              basic_internal_auth_domain:
                http_enabled: true
                transport_enabled: true
                order: "4"
                http_authenticator:
                  type: basic
                  challenge: true
                authentication_backend:
                  type: intern

 

 

4. OpenSearch Dashboards에 등록할 관리자 계정 Secret생성

vi admin-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: admin-credentials
  namespace: logging
type: Opaque
data:
  username: YWRtaW4= # admin
  password: YWRtaW4xMjM=  # admin123
  
kubectl apply -f admin-secret.yaml

 

 

5. OpenSearch 설치

기본적으로 helm chart에 values.yaml 을 수정해서 적용하는 것을 추천하나, 이번엔 바로 적용을 해본다.

인증서를 mount하고, opensearch.yml을 정의하고 securityConfigSecret을 추가하여 관리자 계정을 생성한다.

helm install opensearch-cluster opensearch/opensearch \
--namespace logging --create-namespace
--set clusterName='opensearch-cluster'
--set persistence.storageClass=nfs \ # StorgeClass 가 있으면 설정 없으면 삭제
--set persistence.enabled=false \ # EmptyDir로 실행하고 싶으면 설정 그게아니라면 따로 PV설정필요
# 기본적으로 아래로 적용
--set-json 'extraEnvs=[{"name": "DISABLE_INSTALL_DEMO_CONFIG", "value": "true"}] \
# SingleNode로 설치시 lifecycle 이용할려면 아래로 적용
--set-json 'extraEnvs=[{"name": "DISABLE_INSTALL_DEMO_CONFIG", "value": "true"}
{"name": "OPENSEARCH_USERNAME", "valueFrom": {"secretKeyRef": {"key": "username",
"name": "admin-credentials-secret"}}},
{"name": "OPENSEARCH_PASSWORD", "valueFrom": {"secretKeyRef": {"key": "password",
"name": "admin-credentials-secret"}}}]' \
--set-json 'extraVolumes=[{"name": "certs-secret" "secret": {"defaultMode": 384,
"secretName": "opensearch-cert"}}] \
--set-json 'extraVolumeMounts=[{"mountPath": "/usr/share/opensearch/config/certs",
"name": "certs-secret"}]' \
--set config.opensearch.yml="cluster.name: opensearch-cluster
plugins.security.ssl.transport.pemcert_filepath: certs/node.pem
plugins.security.ssl.transport.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: certs/root-ca.pem
plugins.security.ssl.http.pemcert_filepath: certs/node.pem
plugins.security.ssl.http.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: certs/root-ca.pem
plugins.security.allow_unsafe_democertificates: false
plugins.security.allow_default_init_securityindex: true
plugins.security.authz.admin_dn: ['CN=opensearch-admin']
plugins.security.nodes_dn: ['CN=opensearch*']
plugins.security.audit.type: internal_opensearch
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privilege: true
plugins.security.restapi.roles_enabled: [all_access, security_rest_api_access]
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: ['.opendistro-alerting-config', '.opendistro-alerting-alert*', '.opendistro-anomaly-results*', '.opendistro-anomaly-detector*', '.opendistro-anomaly-checkpoints', '.opendistro-anomaly-detection-state', '.opendistro-reports-*", ".opendistro-notifications-*', '.opendistro-notebooks', '.opendistro-asynchronous-search-response*']
node.max_local_storage_nodes: 3' # Single Node 이면 삭제하고 따옴표 주의
--set securityConfig.config.securityConfigSecret=securityconfig-secret"

 

기타.

https://opensearch.org/docs/latest/security/configuration/system-indices/

를 확인하면 관리자 계정으로도 사용할 수 없는 api들이 있음.

 

5. OpenSearch Dashboards 설치

4번에서 생성한 secret을 넣어준다.

helm install opensearch-dashboards opensearch/opensearch-dashboards \
-n logging --create-namespace \
--set-json 'extraEnvs=[{"name": "OPENSEARCH_USERNAME", "valueFrom": {"secretKeyRef": 
{"key": "username", "name": "admin-credentials"}}},
{"name": "OPENSEARCH_PASSWORD", "valueFrom": {"secretKeyRef": 
{"key": "password", "name": "admin-credential"}}}]

 

Ingress 설정은 맨위에 OpenSearch FluentBit 연동글을 참고한다.

반응형

'Develop > OpenSearch / FluentBit' 카테고리의 다른 글

OpenSearch SingleNode  (0) 2025.03.06
OpenSearch Operator Coordinator  (0) 2025.02.18
Fluent-Bit Systemd Logging  (0) 2025.02.18
opensearch operator read only mode  (0) 2024.12.02
OpenSearch Operator Certificate 설정  (0) 2024.11.28
반응형

 

1. OpenSearch Operator로 설치할 경우 지원하지않는다. 일반 helm으로 설치시 가능하다.

helm install opensearch-single opensearch/opensearch \
--namespace logging \
--set singleNode=true \
--set persistence.enabled=false \
--set-json 'extraEnvs=[{"name": "OPENSEARCH_INITIAL_ADMIN_PASSWORD", "value": "singleNode1!"}]'

 

 

2. 설치 완료 후 접속하여 Cluster 상태를 확인한다.

상태를 확인하면 yellow로 나타는데 이는 Single Node임에도 불구하고 replicas가 1로 설정되어있어서 그렇다

curl -k -u admin:singleNode1! https://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "opensearch-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "discovered_master" : true,
  "discovered_cluster_manager" : true,
  "active_primary_shards" : 5,
  "active_shards" : 5,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 1,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 83.33333333333334
}

# 아래 명령어를 통해 대충 왜 yellow 인지 알 수 있다.
curl -k -u admin:singleNode1! https://localhost:9200/_cluster/allocation/explain?pretty

 

 

3. health Status 변경

_all/_settings 명령어를 통해 모든 index 의 replicas 0으로 변경

curl -k -XPUT -u admin:singleNode1! https://localhost:9200/_all/_settings \
-H 'Content-Type: application/json' -d'
{
  "index": {
     "number_of_replicas": 0
  }
}' --cert ./config/kirk.pem --key ./config/kirk-key.pem


# 다시 status 확인
curl -k -u admin:singleNode1! https://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "opensearch-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "discovered_master" : true,
  "discovered_cluster_manager" : true,
  "active_primary_shards" : 6,
  "active_shards" : 6,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

--cert 와 --key 의 경우 현재 데모인증서를 사용해서 kirk.pem 과 kirk-key.pem을 사용하였다.

데모인증서가아닌 직접 인증서를 설정했으면 설정한대로 해야한다.

 

또한, 해당 API는 만약 Dashbaord를 사용하면 Dashboard의 devtool로도 적용되지 않는다.

적용되게 할려면 따로 opensearch.yml 에 설정해주어야 함. 아래 url 참고

https://opensearch.org/docs/1.3/security/configuration/system-indexes/

 

4. 또한 설치시 replicas 0으로 설정할 수 있다. 

lifecycle 에 index가 replicas 0으로 생성 되도록 template을 추가하는 postStart 를 추가하면된다.

lifecycle:
  postStart:
    exec:
      command:
      - bash
      - -c
      - |
        #!/bin/bash
        until curl -s "https://localhost:9200/_cluster/heatlh" -k -u admin:singleNode1! | grep -q "green\|yellow; do
        sleep 5
        done
        curl -k -u admin:singleNode1! -XPUT "https://localhost:9200/_index_template/single_init_template"
        -H 'Content-Type: application/json' -d'{
          "index_patterns": ["*"],
          "template": {
            "settings": {
              "number_of_replicas": 0
             }
           }
         }'

 

5. 기타

2.19.0 버전부터 Query Insights 라는 plugin이 설치되어 replicas가 1인 top_queries 인덱스가 자동으로 하나 생성되는데,

이것 때문에 health yellow로 되는데 반드시 0으로 수동으로 변경해주어야 green으로 돌아온다

 

반응형
반응형

 

helm chart harbor upload이다

harbor내에 프로젝트 생성 후 진행

helm registry login harbor.wky.kr --insecure
# Input id/password

# harbor에 chart 라는 프로젝트 생성했음
helm push <helm-chart-name>.tgz oci://harbor.wky.kr/chart --plain-http
반응형
반응형

 

OpenSearch Operator Coordinator 설정 방법

 

만약 아래 글을 통해 인증서를 생성했으면, subjectAltName 수정으로 인해 인증서 또한 수정해야한다.

2024.11.28 - [Develop/k8s] - OpenSearch Operator Certificate 설정

# root ca 생성
openssl genrsa -out root-ca-key.pem 2048
openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/CN=opensearch" -out root-ca.pem -days 3650

# OpenSearch Operator가 OpenSearch Cluster를 관리하는 관리자 인증서
openssl genrsa -out admin-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
openssl req -new -key admin-key.pem -subj "/CN=opensearch-admin" -out admin.csr
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 3650

# Node간 DNS 통신을 위해 subjectAltName 생성
echo 'subjectAltName=DNS:opensearch-cluster-masters,DNS:opensearch-cluster-masters.opensearch,DNS:opensearch-cluster-masters.opensearch.svc,DNS:opensearch-cluster-masters.opensearch.svc.cluster.local,DNS:opensearch-cluster-coordinator,DNS:opensearch-cluster-coordinator.opensearch.svc.cluster.local,DNS:opensearch-cluster-coordinator.logging,DNS:opensearch-cluster-coordinator.logging.svc' > san.ext

# OpenSearch Node간 인증서
openssl genrsa -out node-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node-key.pem
openssl req -new -key node-key.pem -subj "/CN=opensearch-cluster-*" -out node.csr
openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node.pem -days 3650 -extfile san.ext

# OpenSearch yaml에 등록할 인증서 파일들 secret으로 생성
kubectl create secret generic opensearch-cert-admin --from-file=ca.crt=root-ca.pem --from-file=tls.crt=admin.pem --from-file=tls.key=admin-key.pem -n opensearch
kubectl create secret generic opensearch-cert-node --from-file=ca.crt=root-ca.pem --from-file=tls.crt=node.pem --from-file=tls.key=node-key.pem -n opensearch

 

OpenSearchCluster yaml 파일 수정

Dashboard가 coordinator 를 보도록 수정하였고 Coordinator를 설정하였다

apiVersion: opensearch.opster.io/v1
kind: OpenSearchCluster
metadata:
  name: opensearch-cluster
  namespace: opensearch
spec:
  security:
    config:
      adminSecret:
        name: opensearch-cert-admin
    tls:
       http:
         generate: false
         secret:
           name: opensearch-cert-node
       transport:
         generate: false
         perNode: false
         secret:
           name: opensearch-cert-node
         nodesDn: ["CN=opensearch-cluster-*"]
         adminDn: ["CN=opensearch-admin"]
  general:
    httpPort: 9200
    serviceName: my-first-cluster
    version: 2.19.0
    pluginsList: ["repository-s3"]
    drainDataNodes: true
  dashboards:
    addtionalConfig: ## hosts 를 coordinator 로 변경
      opensearch.hosts: '["http://opensearch-cluster-coordinator.logging.svc.cluster.local:9200"]'
    tls:
      enable: true
      generate: false
      secret:
        name: opensearch-cert-node
    version: 2.19.0
    enable: true
    replicas: 1
    resources:
      requests:
         memory: "512Mi"
         cpu: "200m"
      limits:
         memory: "512Mi"
         cpu: "200m"
  nodePools:
    - component: masters
      replicas: 3
      resources:
         requests:
            memory: "4Gi"
            cpu: "1000m"
         limits:
            memory: "4Gi"
            cpu: "1000m"
      roles:
        - "data"
        - "cluster_manager"
      persistence:
         emptyDir: {}
    - component: coordinator # coordinator 추가
      replicas:1
      roles:
      - ""
      additionalConfig:
        node.master: "false"
        node.data: "false"
        node.ingest: "false"
        node.remote_cluster_client: "false"
      resources:
         requests:
            memory: "2Gi"
            cpu: "1000m"
         limits:
            memory: "2Gi"
            cpu: "1000m"
      persistence:
         emptyDir: {}

 

 

참고로 Opensearch에서 제공하는 ingest기능을 사용하기 위해서는 ingest node를 생성해야한다.

반응형
반응형

 

Fluent-Bit 을 k8s DaemonSet 으로 실행할 경우 서버 내의 journal 폴더가 /var/log/journal 로 되어있을 경우

마운트 설정이 필요없지만, 아닐 경우 DaemonSet 에 마운트해야한다.

journal이 위치한 경로를 찾아 설정한다.

 

DaemonSet 수정

kubectl edit ds -n fluent-bit -n fluent
...
	spec:
      containers:
      - args:
        -
        ...
        command:
        ...
        volumeMounts:
        - mountPath: /run/log/journal  ## 추가
          name: systemd-log 		   ## 추가
          readOnly: true			   ## 추가
      dnsPolicy:
      restartPolicy:
      ...
      toleration:
      - effect: NoSchedule
        key: node-role.kubernetes.io/control-plane
      volumes:					
      - hostPath:				  ## 추가
          path: /run/log/journal  ## 추가
        name: systemd-log         ## 추가

 

 

수정 후 ConfigMap 수정

kubectl edit cm fluent-bit -n fluent
[INPUT]
    Name systemd
    Path /run/log/journal
    Tag systemd.*
    Systemd_Filter _SYSTEM_UNIT=kubelet.service
    Systemd_Filter _SYSTEM_UNIT=containerd.service
    Read_From_tail On
    
 ## 아래는 없어도 됨
 [FILTER]
     Name record_modifier
     Match systemd.*
     Record kubernetes systemd

 

반응형
반응형

 

k8s Audit Policy 설명이다.

감사로그 설정 자체는 가이드에 잘 되어있어서 그대로 따라하면된다.

https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/

 

1.감사로그에는 단계 및 레벨이 존재한다.

단계

Stage Description
RequestReceived Audit Handler 가 요청을 수신한 직후
ResponseStarted 요청은 받았으나 응답 전
ResponseComplete 요청을 완전히 처리하고 응답 완료
Panic 요청을 처리하는 동안 오류가 발생할 때

 

레벨

Level Description
None 해당 규칙에 해당되는 이벤트는 로깅하지 않음
Metadata 요청된 메타데이터(사용자, 리소스, 시간,verbs) 등은 로깅하지만 요청/응답 내용은 로깅안함
Request 이벤트 메타데이터 및 요청 내용은 로깅하지만 응답은 로깅 안함
RequestReponse 메타데이터, 요청, 응답 로깅 함

 

또한 omitStages 라는 것이 있는데, 해당 필드는 전역으로 줄 수도 있고 지역으로도 설정하여 단계를 제외시킬 수 있다.

기본적으로 단계를 설정하지않으면, 모든 단계(발생할 경우)를 호출한다.

 

2. 예제

2.1 Level 을 Metadata로 설정 했을 경우

본문 내용은 로깅되지않고 기본적인 메타데이터와 RequestReceived, ResponseComplete 호출

(ResposneStarted와 Panic 은 특수한 경우에 호출되는 듯함)

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: metadata
    resources:
      - group: ""
        resources: ["*"]
        

# result
{
    "kind" : 
    "apiVersion" :
    "level" : "Metadata"
    "auditID" :
    "stage" : "RequestReceived"
    "requestURI" :
    "verb":
    "user": {
    }
    ...
}
{
    "kind" : 
    "apiVersion" :
    "level" : "Metadata"
    "auditID" :
    "stage" : "ResponseComplete"
    "requestURI" :
    "verb":
    "user": {
    }
    ...
}

 

2.2 모든 요청의 단계 대해 RequestReceived 제외하고 Level은 Metadata인 경우

위의 결과와 달리 RequestReceived 로깅안함.

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: metadata
    resources:
      - group: ""
        resources: ["*"]
        

# result
{
    "kind" : 
    "apiVersion" :
    "level" : "Metadata"
    "auditID" :
    "stage" : "ResponseComplete"
    "requestURI" :
    "verb":
    "user": {
    }
    ...
}

 

omitStages는 위에 설명한대로 전역 또는 지역에도 설정 가능

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: metadata
    omitStages:
      - "RequestReceived"
    resources:
      - group: ""
        resources: ["*"]

 

2.3 모든 요청의 단계 대해 RequestReceived 제외하고 Level은 Request인 경우

RequestReceived 로깅안하며, 요청내용의 Body만 로깅, 응답 Body는 로깅안함.

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: Request
    resources:
      - group: ""
        resources: ["*"]
        

# result
{
    "kind" : 
    "apiVersion" :
    "level" : "Request"
    "auditID" :
    "stage" : "ResponseComplete"
    "requestURI" :
    "verb" :
    "user" : {
    }
    "responseStatus": {
    }
    "requestObject": {
    	"kind" : "Pod",
        "apiversion" :
        "metadata" : {
        }
        "spec : {
          "volumes" : {
          }
          "containers" : {
          }
        ...
    }
}

 

이 외에도 특정 namspace 및 특정 사용자만 로깅 또는 로깅제외 시킬 수가 있다.

 

참고 :

https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/

반응형
반응형

 

k8s 에서 1.24 이전 버전에는 service account secret token이 자동으로 생성 되었지만,

이후 버전 부터는 직접 생성하고 관리해주어야 한다.

특히 토큰에는 수명주기가 있으며 이를 관리해주어야 한다.

임시 기간 토큰 생성 및 영구 생성, Refresh를 통한 토큰 관리가 있다.

 

1. 임시 기간 토큰 생성

kubectl create token 명령어를 통해 토큰 생성이 가능하며, --duration 옵션을 통해 시간 지정 가능하다.

duration 옵션이 없을 경우 기본적으로 1시간으로 세팅된다.

또한, 해당 명령어로 토큰을 생성할 경우 생성할 때 조회 가능하고 더 이상 생성한 토큰에 대해 조회가 불가능하다.

# 임시 계정 생성
kubectl create sa temp-sa

# create token 명령어를 통해 임시 생성
kubectl create token temp-sa --duration 30m

# result
eyJhbGciOiJSUzI1NiIsImtpZCI6ImU1Mnp2SFpHYS1RN2dXaElkV0tEZC1nemlxeTFhdWQiGE5ZC1hM2E3LTQ4OGYtOTM3OS1iYzc0MGU1ZjUyMDkifX0sIm5iZiI6MTczNDQzOTY4MCwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6dGVtcC1zYSJ9.Ya83wdlUMifQww_XUmK2rEfxkAMqueDT6QeYiQqwXlWYnUIq4YaCZDbo7XZz8xW3W-_efpx1-7n9dHkUMzk88LvCCS5C0S6J89hGGAI4T_nhyTfIhj4AbC_hhLdZR3b9pSuh7a0xY_CiD
{
    "aud": [
        "https://kubernetes.default.svc.cluster.local"
    ],
    "exp": 1734441480,
    "iat": 1734439680,
    "iss": "https://kubernetes.default.svc.cluster.local",
    "jti": "360425d7-587d-44ca-8633-67e5e07ac9e5",
    "kubernetes.io": {
        "namespace": "default",
        "serviceaccount": {
            "name": "temp-sa",
            "uid": "34bd8a9d-a3a7-488f-9379-bc740e5f5209"
        }
    },
    "nbf": 1734439680,
    "sub": "system:serviceaccount:default:temp-sa"
}

 

 

2. 영구 토큰 생성

영구 토큰은 Service Account 생성 후 Secret을 따로 생성해주면 된다.

하지만, 권장하지는 않는다.

# 계정 생성
kubectl create sa permanent-sa

# secret 생성
vi secret.yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: permanent-sa-secret
  annotations:
    kubernetes.io/service-account.name: permanent-sa
    
# 적용
kubectl apply -f secret.yaml
 
# 조회
kubectl get secret
NAME                               TYPE                                  DATA   AGE
permanent-sa-secret                kubernetes.io/service-account-token   3      4s

# 토큰 조회
kubectl describe secret apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: permanent-sa-secret
  annotations:
    kubernetes.io/service-account.name: permanent-apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: permanent-sa-secret
  annotations:
    kubernetes.io/service-account.name: permanent-sa
root@master:~/account# kubectl describe secret permanent-sa
Name:         permanent-sa-secret
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: permanent-sa
              kubernetes.io/service-account.uid: 349d3c79-1180-4cea-9357-5169a7a88d4c

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImU1Mnp2SFpHYS1RN2dXXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3V
ca.crt:     1107 bytes
namespace:  7 bytes

 

 

3. Service Account Mount를 통한 갱신

 

3.1 기본적인 Mount 를 통한 갱신

기본적으로 pod yaml 설정시 Service Account를 적용하게되면 1시간마다 토큰이 갱신된다.
(확인하려면 1시간 후 pod 에 접속해서 확인 가능, 공식문서에서도 1시간마다 kubelet이 갱신한다고 나와 있음)

# 토큰 생성
kubectl create sa auto-sa

# deploy.yaml 내 serviceAccount 적용
...
spec:
  template:
    spec:
      serviceAccount: auto-sa
      containers:
      ...
...

# 토큰 조회를 위해 pod 접속
kubectl exec -it stdout-node-869cff8b95-cxqf2 -- sh

# 경로
pwd
/var/run/secrets/kubernetes.io/serviceaccount

ls
ca.crt     namespace  token

# 토큰 조회
# 토큰이 변경되는걸 확인하려면 1시간 후에 해당 pod 접속해서 똑같이 확인하면 됨.
cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6ImU1Mnp2SFpHYS1RN2dXaElkV0tEZC1nemlxeTFMclJubTVTaFhoVkZIY2sifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzY1OTc2NzIxLCJpYXQiOjE3MzQ0NDA3MjEsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiNjQ3ZDZmYWMtODc

 

 

3.2 Volume Project 를 통한 관리

위 방법 말고 Volume Project를 통한 시간 설정 및 갱신이 가능하다.

automountServiceAccountToken 옵션을 false 로 주어야하므로 yaml로 생성
기본적으로 ServiceAccount 생성시 true 로 생성 됨.

해당 예제는 2시간으로 설정

(2시간뒤 자동 갱신됨)

# automountServiceAccountToken 옵션을 false 로 주어야하므로 yaml로 생성
# 기본적으로 ServiceAccount 생성시 true 로 생성 됨.
vi passive-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: passive-sa
  namespace: default
automountServiceAccountToken: false

# deploy.yaml 내 serviceAccount volume project 적용
...
spec:
  template:
    spec:
      serviceAccount: passive-sa
      volumes:
      - name: project-passive-sa
        projected:
          sources:
          - serviceAccountToken:
              path: passive-account-file
              expirationSeconds: 7200
      containers:
        volumeMounts:
        - mountPath: /tmp/token
          name: project-passive-sa
...

# 토큰 조회를 위해 pod 접속
kubectl exec -it stdout-node-7fcc7ff87-tjfjf -- sh

# 경로
# 위에서 /tmp/token 에 설정했음
pwd
/tmp/token

# 위에서 passive-sa-file 로 설정했음
ls
passive-sa-file

# 토큰 조회
# 토큰이 변경되는걸 확인하려면 2시간으로 설정했으므로 2시간 후에 해당 pod 접속해서 똑같이 확인하면 됨.
cat passive-sa-file 
eyJhbGciOiJSUzI1NiIsImtpZCI6ImU1Mnp2SFpHY

 

 

3.3 TokenRequest API 이용

API 호출용, 일반 Service Account 2개를 만들어, 하나는 Token 갱신을 위해 사용하는 방법으로 사용한다.

또는 하나의 계정을 통해 직접 갱신해서 사용한다.

pod 에 접속해서 아래 API를 호출하면된다.

curl -k --header "Authorization: Bearer token" https://kubernetes.default.svc/api/v1/namespaces/default/pods

 

 

참고 :

https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/

https://kubernetes.io/docs/concepts/security/service-accounts/

반응형
반응형

 

opensearch 무료지만 가이드가 너무하네

 

OpenSearch Dashboard Operator로 설정시  readolny 설정

대충입력하면 배열로 입력하라는데 아래와 같이 입력해야함.

다른 설정도 배열과 같이 입력하라면 아래와 같이 쌍따옴표 및 대괄호해서 입력하면 됨.

진짜 가이드 너무할정도로 별로임...

apiVersion: opensearch.opster.io/v1
kind: OpenSearchCluster
#...
spec:
  dashboards:
    additionalConfig:
      opensearch_security.readonly_mode.roles: "['readonly']"
반응형
반응형

 

k8s cluster를 kubernetes admin을 사용하는게 아닌 인증서를 통한 사용자를 생성하여 k8s cluster를 사용하는 방법이다.

 

1. 개인키 생성

# key 생성
openssl genrsa -out pangyeon.key 2048

# csr 생성
openssl req -new -key pangyeon.key -out pangyeon.csr -subj "/CN=pangyeon"

# csr 값 조회
cat pangyeon.csr | base64 | tr -d "\n"
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1dEQ0NBVUFDQVFBd0V6RVJNQThHQTFVRUF3d0ljR0Z1WjNsbGIyNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGpFa0FaSmhBdElhcTEzSjczREFsa1R4cUExeGdQRWx6dkxXbEVzdzdLCjBRQ29YMGdBR3JFVTlQcDNubWl2U051T0dKd0F4REN3dFQ1TThteDd2a21ZNHRPRC80ZWhVVGhQd3FhOXMwUjMKUUQ5SHlWQ0hqcm1PV1ZDempmNWJ5WkJXc3RZSjZxcGQ2ZUc2NVRlbDF0RmdNRHM4QUdsNmNiazJ4SE1WK2s2dQpNTkVsV3FnRGUwTmt1S3hLWW5OZnY5QWVRanlSek1NUm5Ia1c0cTNucFRqaXhnWTY4eFhzdHpQUlpTZ0YwVU8wCjdUdjlSRE5VdlVKQ3NBdzlrSFlObXdGWkw3SHNtcHdHV3lNdWRCVVVBQ0w3dFUyL0MwZFQ2VkpuSzBmV1VnVlMKNWtRK0NkdW5BdHVDTm8xOTdLS2hQalR5OXE3c1NnajVlcmltNEtGNkdIN2hBZ01CQUFHZ0FEQU5CZ2txaGtpRwo5dzBCQVFzRkFBT0NBUUVBMnJxbHFGTHJjVUhkRU5qclQvVkxOUE5IVEFNMElyTEROVlVsWFRBSDA5S1JQZCsvCkNyUkF3TVEzOXJqRjE5R213Y1czZHNnSkRXR2NacXcxV1JTRlplQy9UaklJZXUzM0EvRm55TC8vYXVUZWg5REEKaEROcURTdnZpNEQzbmwyOTVGNFVMdzJVZG9QbTRyaWxzUHh0eEU3U1dUSFlpYm90QmZnSjJ2NUExb085UU5JeAo4NUE0eHJBVEEvR1EycWZhSlRhZ2pSUGQrNUVHK0tkTm85cnN0Vjl2Y3ZyTkdzS2F0YXpYL2dCTEhoWW9EMzVXCjJ0UFBCSUhmSUU4UUtmakJtZGJKQzlMY2o2UU00V2FDOVJRd293KzFEbTMwZnhmRjWVMVUszckVac3MKU21xVFphZFpWek9XWDdEQnVzM1A5V3lWOExU

 

 

2. CertificateSigningRequest 생성

# CertificateSigningReques 생성
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: pangyeon
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQTUEwR0NTcUdTSWIzUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRGpFa0FaSmhBdElhcTEzSjczREFsa1R4cUExeGdQRWx6dkxXbEVzdzdLCjBRQ29YMGdBR3JFVTlQcDNubWl2U051T0dKd0F4REN3dFQ1TThteDd2a21ZNHRPRC80ZWhVVGhQd3FhOXMwUjMKUUQ5SHlWQ0hqcm1PV1ZDempmNWJ5WkJXc3RZSjZxcGQ2ZUc2NVRlbDF0RmdNRHM4QUdsNmNiazJ4SE1WK2s2dQpNTkVsV3FnRGUwTmt1S3hLWW5OZnY5QWVRanlSek1NUm5Ia1c0cTNucFRqaXhnWTY4eFhzdHpQUlpTZ0YwVU8wCjdUdjlSRE5VdlVKQ3NBdzlrSFlObXdGWkw3SHNtcHdHV3lNdWRCVVVBQ0w3dFUyL0MwZFQ2VkpuSzBmV1VnVlMKNWtRK0NkdW5BdHVDTm8xOTdLS2hQalR5OXE3c1NnajVlcmltNEtGNkdIN2hBZ01CQUFHZ0FEQU5CZ2txaGtpRwo5dzBCQVFzRkFBT0NBUUVBMnJxbHFGTHJjVUhkRU5qclQvVkxOUE5IVEFNMElyTEROVlVsWFRBSDA5S1JQZCsvCkNyUkF3TVEzOXJqRjE5R213Y1czZHNnSkRXR2NacXcxV1JTRlplQy9UaklJZXUzM0EvRm55TC8vYXVUZWg5REEKaEROcURTdnZpNEQzbmwyOTVGNFVMdzJVZG9QbTRyaWxzUHh0eEU3U1dUSFlpYm90QmZnSjJ2NUExb085UU5JeAo4NUE0eHJBVEEvR1EycWZhSlRhZ2pSUGQrNUVHK0tkTm85cnN0Vjl2Y3ZyTkdzS2F0YXpYL2dCTEhoWW9EMzVXCjJ0UFBCSUhmSUU4UUtmakJtZGJKQzlMY2o2UU00V2FDOVJRd293KzFEbTMwZnhmRjdUN05XdWVMVUszckVac3MKU21xVFphZFpWek9XWDdEQnVzM1A5V3lWOExUOFZKVG1H
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
EOF

# 생성한 CertificateSigningRequest 조회
kubectl get csr
NAME       AGE   SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
pangyeon   48s   kubernetes.io/kube-apiserver-client   kubernetes-admin   24h                 Pending

# 승인 요청
kubectl certificate approve pangyeon

# 승인확인
kubectl get csr
NAME       AGE     SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
pangyeon   5m17s   kubernetes.io/kube-apiserver-client   kubernetes-admin   24h                 Approved,Issued

# 승인한 인증서 추출
kubectl get csr pangyeon -o jsonpath='{.status.certificate}'| base64 -d > pangyeon.crt

 

 

3. Cluster Role 생성

해당 예시는 모든 자원에 대해 View 권한 부여

# CluserRole, CluserRolebinding 생성
vi role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-only
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-only-binding
subjects:
- kind: User
  name: pangyeon
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: read-only
  apiGroup: rbac.authorization.k8s.io
  
# 적용
kubectl apply -f role.yaml

 

 

4. Contexts 생성

# Credentials 생성
kubectl config set-credentials pangyeon --client-key=pangyeon.key --client-certificate=pangyeon.crt --embed-certs=true

# Context 추가
kubectl config set-context pangyeon --cluster=kubernetes --user=pangyeon

# 조회
kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
          pangyeon                      kubernetes   pangyeon
          
# 사용
kubectl config use-context pangyeon
Switched to context "pangyeon".

 

 

5. 테스트

조회시 인증서로 추가된 부분 확인 및 권한으로 인해 조회만 가능하고 삭제 불가

# 조회시 인증서로 계정 추가된 것 확인
cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJSFl4OUR6MmlDUHN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QkpoeWJCdElXSE1KRHY4WUtlQ2o0SEJ3MzlKT0E5MXJwcld0UURlUE4KYzRwWEZVMTQ5L1VZTSs2Q3hLZUtVTXphK0EyQU9vRzFMbUhzbzZYMktEYm5TRFlidFk2dDVLNFBlUmI1NXhMbAplRnZ5eDlzKzgxc0RZZGZVSlFVSlR4TEo1em9VOFlPQldhWjRrdUJObkF1TVJkbE40LzNCNnNwNkUrOXY2TDB2ClVGelpqYmhocFJyZjJ0TmZJV2hiU3Q4am9xcCtWc2hRMDZIN09WUU5nR1BwNGxxZGR5ZGJ4aGhKYWJvbnJMZ2oKTTF0elU0UFVadjFDVjh3dWRHclV4dDIxNkgwSC83SGN5UHRMWnE4MmpWOGl1Zk9FQzV5OFd5VHBBL25mcDJaNAp6RmR2ZjdpdkRaSXFhUjJQSTVScUxxeGNDOEJoQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRd0hCQ0NJRHJZQ29OckRIancyNXVVOSs3RTFqQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQThvZ1lQVjQrZwo5cHEwN0FZUStzbittdmNaVi93ZE9wbml3bkt1NXBBY1plWG1aQU1wOExEaUcwRWJ5RkJFdlNqWTZ6RmxIa2xmCjZNRE1QM1NPVXl0cmZ2Qnd5ZEpVdjNtOXNKOXdpYU1OY0RCekJXdlFNZ0NPQktWWXB2UTZHY05UOGEvdWV5UDYKVC9rQnNyeXhLNDV4OWMvSXRCVHVoOTdzMFgvTkthNHd2eTVJelg0YmZzVkJrVHpQdTVlRVRPZmtoWWY2aUxLNgpBV0ZiQWJWTUN0NWxsWFdxb2VtRm4wRm9ERDROdjV3ejQ0M3FmSTVRTktaQlBMUHZFTXMwMEo2RHNJY1NjOUoxCnpET3hWTVRJUk5ieUpWMk5GV2hYdXlLTUNUS05iUzgraGgvazVTVk41TUc3ZjBSVUdmSm1XV2N2SE0zS3Q5RXIKNitEREJ6aHgyZVppCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://127.0.0.1:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: pangyeon
  name: pangyeon
current-context: pangyeon
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJWUxSTnZQOFl4Qnd3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TkRFd016QXhORFF4TWpkYUZ3MHlOVEV3TXpBeE5EUTJNamRhTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDZ2xVWmkKYWFweHBaYWdTT2wvcnpTckkzaWJFbUFpa2cyMVNqUGVMMXQ1U21jeEVINnNjUVZTcjV5REd4WUI1ZElLa0lrNwpSN0oyUGVlQi92RFFmbXdrUEQrUlE2bnFkS1QyM0c3R09QeDJla2pwcnJ2ejd4T0xjNGJDVURPTWVGcXl4TjVqClIrZTVSM2w1S3NQU2NxUUs4cTlDSUNVUXJ2NVplYVV1TW96NnFWQXZ3ZWtwZzNZanM2STlwWjJrWTEwTzRwYVAKZHRJTHcyU1NYSUR6YWNCa2txVy9SM1ZUR3ZNdHlqU1Nwak9YMVBwNkEwbHJOaUl1RzA5cDhOanI2U1VsMlptSwpvWGZweXBRV2p2UUJ4aUVXTVB1M2lqcTY3cmhQUVlhTWFmMzJjWmRhRHpFNHBqaTMxS2habWxUTCtlZS9YanhoClZwcWY2MmZIUFVyb01HMkxBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkRBY0VJSWdPdGdLZzJzTQplUERibTVUMzdzVFdNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUIrSys4MGVkNWJzNDhNM09acXBtbVdhNmdiCnd5bXl2c3BCZ1JNSGNLQXNMNTNuejNOaytYcDJZRUp1R3h2TDR4RlR0RWUxalhxRzRidkowUWJQcGhtdi9JRkEKWWJHUGNQU3YzMDR2WWhLcnBPMlc3NkE2ZUtFUUFxcS9YVzFaK0VTNEhMTUFYQWtLNzZ0dXNXV3lmY3pxb2NJMwpoYTc2bklBSjA5dkR6VlJQb2VWVGV4TmdWdEYvSFR5b1B1cGFaREhBV1FtOTBPUlduQmM4dHR5Z1pQdU4rVVI0CnFRYTJqRDJySmQ2UXREMUFTT2hkOFNtTHpJTkNBYlVtdXhTZXVZVkNHSy9oUWlWZS9EYVRPL1V4VXRUZStDb1oKYmFNbHBKNk96dVFQZzRZQVBsUXFvYisvSW1hSlVablFPYzdWQWxzN3QwWFEvTDF6Mmpxb0N4OWovcW56Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb0pWR1ltbX
- name: pangyeon
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrRENDQWVDZ0F3SUJBZ0lRTno0OVVBM2h5QUlVZFY5NUVDbVdQakFOQmdrcWhraUc5dzBCQVFzRkFEQVYKTVJNd0VRWURWUVFERXdwcmRXSmxjbTVsZEdWek1CNFhEVEkwTVRFeU9URTBNVGN5TWxvWERUSTBNVEV6TURFMApNVGN5TWxvd0V6RVJNQThHQTFVRUF4TUljR0Z1WjNsbGIyNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRGpFa0FaSmhBdElhcTEzSjczREFsa1R4cUExeGdQRWx6dkxXbEVzdzdLMFFDb1gwZ0EKR3JFVTlQcDNubWl2U051T0dKd0F4REN3dFQ1TThteDd2a21ZNHRPRC80ZWhVVGhQd3FhOXMwUjNRRDlIeVZDSApqcm1PV1ZDempmNWJ5WkJXc3RZSjZxcGQ2ZUc2NVRlbDF0RmdNRHM4QUdsNmNiazJ4SE1WK2s2dU1ORWxXcWdECmUwTmt1S3hLWW5OZnY5QWVRanlSek1NUm5Ia1c0cTNucFRqaXhnWTY4eFhzdHpQUlpTZ0YwVU8wN1R2OVJETlUKdlVKQ3NBdzlrSFlObXdGWkw3SHNtcHdHV3lNdWRCVVVBQ0w3dFUyL0MwZFQ2VkpuSzBmV1VnVlM1a1ErQ2R1bgpBdHVDTm8xOTdLS2hQalR5OXE3c1NnajVlcmltNEtGNkdIN2hBZ01CQUFHalJqQkVNQk1HQTFVZEpRUU1NQW9HCkNDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3SHdZRFZSMGpCQmd3Rm9BVU1Cd1FnaUE2MkFxRGF3eDQKOE51YmxQZnV4Tll3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUZVRXlwNU1HS29YbmUzWjBRSG56N2ZZYVd3OAoyRE14SUdhWGZnSFR5dFlMM01SUGhqYlNXQXl1d0Z5alFSRVhWNTdIMm1iYTY2YjF6eDRvcHhTUFRXRFBValFjCkJ5bkg0b1c4TUs0b1BWSXJzWU9YcUVjVlZqZUhndEcwN1VCb0lTZlhvRnc4dWEwNS9EczJmaVhQbDZXSVpwSTYKTGovY2hhd25rSG8vbnk4QTVaWTRIbVI1UjdXL09uSnlmbW9BN244c3hydzhCN2NURXdpajgxUTBLbWtVT2crNgp2MVdwQlE0MHZMRWZUSnJuczE4TitxOW94Sk5SOGNRY2ZhW
    client-key-data: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRGpFa0FaSmhBdElhcTEKM0o3M0RBbGtUeHFBMXhnUEVsenZMV2xFc3c3SzBRQ29YMGdBR3JFVTlQcDNubWl2U051T0dKd0F4REN3dFQ1TQo4bXg3dmttWTR0T0QvNGVoVVRoUHdxYTlzMFIzUUQ5SHlWQ0hqcm1PV1ZDempmNWJ5WkJXc3RZSjZxcGQ2ZUc2CjVUZWwxdEZnTURzOEFHbDZjYmsyeEhNVitrNnVNTkVsV3FnRGUwTmt1S3hLWW5OZnY5QWVRanlSek1NUm5Ia1cKNHEzbnBUaml4Z1k2OHhYc3R6UFJaU2dGMFVPMDdUdjlSRE5VdlVKQ3NBdzlrSFlObXdGWkw3SHNtcHdHV3lNdQpkQlVVQUNMN3RVMi9DMGRUNlZKbkswZldVZ1ZTNWtRK0NkdW5BdHVDTm8xOTdLS2hQalR5OXE3c1NnajVlcmltCjRLRjZHSDdoQWdNQkFBRUNnZ0VBTzBQYktQVXZTYWc4MXdTREZQVzJTZEQvbU5zSzgzd1dkM0tCeENWNzJlR2MKNjFVYkJMUHl2Z2FHak12eWhMVmVZSUw1ekpWb0krYmFJTmt4Q1VjTURIUS9RbmRpSGUrRjVBTm80NkF6WVhDSwpVNkV1ZklMNjJUVmtnOGl1dDZRdklRSENMWXBxOXVJQlFYZHNBOFBDbC9sZXJIVnJFa00yVlI0Rzc1aUtDcHBECk9hSzB0VWJPWnNkQnlHOWg2eWF0Wk90cVhOMktKSzVJK0J4dVpnVHMxUGhENHNqSnBBRUxhb3M4dHFicG56cDEKNDZYZUtjTlU1Ky9FSHBwaEdTdEExRzdLRDBaSWVHRmZ6SEdFUmk3aXVhZzEvV1hjdk9Cc3I2NXd1U3NyYU1QVApIRTNkcXNoUXdNK1dDYlQ1djBtWFMrRWdOWFN5SXRUQXpydVk4MWMxQlFLQmdRRDZjNlZSV1gyQzBISEpQWHBsCkdiaTJ2cmQwY1NseTY2VEJnc0xkYzdZYWdmQ0VTY3BBQTFuWEQrRWR4V29MS084UGl3S0ZVbUJqZFI4NVk2NXIKakdObGN2NytwRmJSZ3dXZjk5TzZsdjE0Ty80RXdUWkF3ZjRnSHlGKzRodUJScjBJL0loa0cyRmV2WmZ6RWdOWApLSExLRVJwVEJCU0h6SVZ0UEVVUk5YbWxId0tCZ1FEb0dnS1hBVGo2bzlqWWZSODNjQ1l3Njk2cUFzdmpCbTFVCkJDdnQ3ZzRPY00wN3UrWW5hKytuQm5pYUZJY0JZTzd2b3VMUGhrVGlXSlFTREhKcFIxWkNtWGFaMXFaZERjNHIKT283TldFZlFKRXAvOEdFck9nRDJ6YXZSNk9LUGl1dyt6UTE2V1hMamxkQ0lpRVc4UVN5cEM2dW9Oa0tYWUxxRApGWWhkeldWYi93S0JnUURWeGM0dkVLYWIrTldXd3Izcys3WjViWEpqbG8rZGd0dGZQUUNkU3ozOWhEbktnTDE4ClJCL3ovSjdXN1lGbFF5eENaUkhpd0h4N2lDWDlzMExXazc3bmdlOTdaTVNpRWliRDh5SXJHdVFCTTV2UGJTZWsKd0xEcnRBYkFLYmoyY0cyNzlPbHFJU0RNWUNJSm5LOXpQcGcwTjhMelp3RXJKSHdpMEJYWDZZQUtXd0tCZ0g3TApSc0xyZmc4ZVZ5WGRKS0tLZDdLZUNDUGtKekc4bnhrWXRrN2lqM2RBRkQ0ZnBkbS9VMHB4ZEl6bnplRG83VjZvCkl6T3ZiQTRpeWJFYWI1NG54RzNabkRycVVqUGZpTk9BeCtaUjVkbEZHaFhPWWFiVnB4VXN3a0tIOE16dDNhVnAKSzRXOU85QXNWYUZnb0lmNUtzYW1nMzMvTmwyd0QvUHdYWEN3OWtCTkFvR0JBSldScDk0OW1CcU1za2lwTzNhWAp5NnNuYlJ2Y3JhdmJFTUx2UHdISmRJdVg2Kzg0WGdUcHRwREJVZWpyRkhZM1FmVXA2VytnSngzaHFnOTQwV2I1CnhEM2lNblVzamhoZW4vSmtwN3Fma25SWmVGRUdTVVZ
    
# 조회
kubectl get pods
NAME                           READY   STATUS 
stdout-node-6f945d7989-6xjp2   1/1     Running 

# Read권한만 있어 삭제 불가
kubectl delete pods stdout-node-6f945d7989-6xjp2 
Error from server (Forbidden): pods "stdout-node-6f945d7989-6xjp2" is forbidden: User "pangyeon" cannot delete resource "pods" in API group "" in the namespace "default

 

 

참고 : https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user

반응형
반응형

 

OpenSearch Operator 설치시 인증서 설정하는 방법이다.

(가이드가 진짜 너무 너무 심하게 불친절하게 되어있음.... )

 

1. 먼저 자체 서명 인증서를 생성한다.

가이드에는  딱히 어떻게 뭘 생성하라는 얘기는 없으며, 인증서가 하나만 있으면 된다고 나와있으나

사실상 root-ca 와 Admin 인증서, Node 인증서가 필요하다.

또한, adminSecret 역시  tls.crt와 tls.key만 있으면 된다고 나와있지만 ca.crt 가 필요하며,

각종 필드에 대한 설명들이 많이 부족하다.

 

Admin인증서의 경우 OpenSearch Operator가 OpenSearch Cluster를 관리하는관리자 인증서이며,

Node 인증서의 경우 OpenSearch Node 인증서이다. Node인증서는 각 Node별로 만들어서 관리할 수 있으나,

해당 가이드는 하나만 만들어서 공유하는 방법이다.

 

subjectAltName에 들어가는 내용들은 OpenSearch cluster 설치시 포함되는 metadata의 name기준으로 만들어야하며,

OpenSearch Cluster가 생성되면서 뒤에 masters가 붙기 때문에 masters는 반드시 포함한다.

# root ca 생성
openssl genrsa -out root-ca-key.pem 2048
openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/CN=opensearch" -out root-ca.pem -days 3650

# OpenSearch Operator가 OpenSearch Cluster를 관리하는 관리자 인증서
openssl genrsa -out admin-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
openssl req -new -key admin-key.pem -subj "/CN=opensearch-admin" -out admin.csr
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 3650

# Node간 DNS 통신을 위해 subjectAltName 생성
echo 'subjectAltName=DNS:opensearch-cluster-masters,DNS:opensearch-cluster-masters.opensearch,DNS:opensearch-cluster-masters.opensearch.svc,DNS:opensearch-cluster-masters.opensearch.svc.cluster.local' > san.ext

# OpenSearch Node간 인증서
openssl genrsa -out node-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node-key.pem
openssl req -new -key node-key.pem -subj "/CN=opensearch-cluster-masters" -out node.csr
openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node.pem -days 3650 -extfile san.ext

# OpenSearch yaml에 등록할 인증서 파일들 secret으로 생성
kubectl create secret generic opensearch-cert-admin --from-file=ca.crt=root-ca.pem --from-file=tls.crt=admin.pem --from-file=tls.key=admin-key.pem -n opensearch
kubectl create secret generic opensearch-cert-node --from-file=ca.crt=root-ca.pem --from-file=tls.crt=node.pem --from-file=tls.key=node-key.pem -n opensearch

 

 

2. OpenSearch Cluster를 생성할 yaml파일 작성

securityConfig 에는 OpenSearch Operator가 OpenSearch Cluster를 관리하는관리자 인증서를 추가해야하며,

transport secret과 http secret dashboard의 tls secret에는 Node 인증서를 추가하면된다.

그리고 metadata name과 위에 생성한 subjectAltName에 포함된 DNS의 이름과 맞춰주어야 한다.

nodesDn은 root-ca에 생성한 subj 를 입력하고 wildcard를 추가해도된다.

adminDn은 관리자 인증서 생성할 때 입력하였던 subj를 추가한다.

apiVersion: opensearch.opster.io/v1
kind: OpenSearchCluster
metadata:
  name: opensearch-cluster
  namespace: opensearch
spec:
  security:
    config:
      adminSecret:
        name: opensearch-cert-admin
    tls:
       http:
         generate: false
         secret:
           name: opensearch-cert-node
       transport:
         generate: false
         perNode: false
         secret:
           name: opensearch-cert-node
         nodesDn: ["CN=opensearch-cluster-masters*"]
         adminDn: ["CN=opensearch-admin"]
  general:
    httpPort: 9200
    serviceName: my-first-cluster
    version: 2.14.0
    pluginsList: ["repository-s3"]
    drainDataNodes: true
  dashboards:
    tls:
      enable: true
      generate: false
      secret:
        name: opensearch-cert-node
    version: 2.14.0
    enable: true
    replicas: 1
    resources:
      requests:
         memory: "512Mi"
         cpu: "200m"
      limits:
         memory: "512Mi"
         cpu: "200m"
  nodePools:
    - component: masters
      replicas: 3
      resources:
         requests:
            memory: "4Gi"
            cpu: "1000m"
         limits:
            memory: "4Gi"
            cpu: "1000m"
      roles:
        - "data"
        - "cluster_manager"
      persistence:
         emptyDir: {}

 

이후 해당 yaml파일을 적용하면 문제없이 생성된다.

 

참고로 tls transport 는 반드시 인증서를 적용해주어야 한다.(필수임)

반응형

+ Recent posts