Grafaka SSL 방법 1. [ AWS NLB, AWS ACM 사용]


개념설명 : AWS NLB 에서는 SSL offload 기능을 지원함으로써 인증처리를 진행 할 수 있다

User -----ⓐ-----> NLB -----ⓑ-----> Grafana 
위 구성으로 흐름이 진행 될때 

1. ⓐ 구간에서는 https 를 사용한 통신이 진행
2. ⓑ 구간에서는 NLB 가 SSL offload 기능을 지원함으로써 NLB 와 Grafana 사이에서는 SSL 통신이 아닌 http 통신이 이루어진다

장점 : Grafana 설정의 변경 없이 NLB 구성만으로 인증 적용이 가능
단점 : 모든통신이 암호화 되어야 한다는 조건이 있어야 한다면 해당 기능은 위배됨

 

 

1. Grafana SSL의 경우 EKS에서 구성을 하여 앞단 NLB를 사용하여 SSL 구성

Grafana.ini 설정은 아래와 같음

  • protocol : http
  • http_port: 3000

2. Grafana 설치한 SVC 에서 LB를 NLB로 설정

  • annotations -> service.beta.kubernetes.io/aws-load-balancer-type: nlb
  • port 443 -> targetgroup : 3000

 

3. Grafana SVC 로 생성된 LB 설정 변경

  • protocol : tls
  • port : 443
  • key : ACM 에 등록해 놓은 key value

 

 


Grafaka SSL 방법 2. [k8s secret 사용]

인증서가 있다는 가정 하에 방법만 소개

1. k8s secret 에 인증 정보를 등록

kubectl create secret tls {secret Name} --key {key file 위치} --cert {cert 파일 위치}

ex) kubectl create secret tls grafana-tls --key ./grafana.pem --cert grafana.crt

2. Grafana.ini 수정

  • server 부분에 아래와 같이 인증을 위한 구문 추가
apiVersion: v1
data:
  grafana.ini: |
    [analytics]
    check_for_updates = true
    [grafana_net]
    url = https://grafana.net
    [log]
    mode = console
    [paths]
    data = /var/lib/grafana/
    logs = /var/log/grafana
    plugins = /var/lib/grafana/plugins
    provisioning = /etc/grafana/provisioning
    [server]
    domain = ''
    protocol = https
    http_port = 3000
    cert_file = /etc/grafana/certs/tls.crt
    cert_key = /etc/grafana/certs/tls.key
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: grafana
    meta.helm.sh/release-namespace: default
  creationTimestamp: "2023-01-08T10:53:50Z"
  labels:
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: grafana
    app.kubernetes.io/version: 9.3.1
    helm.sh/chart: grafana-6.49.0
  name: grafana
  namespace: default

3. Grafana deploy 수정

  • livenessProbe 수정 [HTTP -> HTTPS]
  • readnessProbe 수정 [ HTTP -> HTTPS]
  • volumeMounts 수정 [secret 정보 추가]
  • volumes 수정 [ secret 정보 추가]
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "11"
    meta.helm.sh/release-name: grafana
    meta.helm.sh/release-namespace: default
  creationTimestamp: "2023-01-08T10:53:50Z"
  generation: 11
  labels:
    app.kubernetes.io/instance: grafana
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: grafana
    app.kubernetes.io/version: 9.3.1
    helm.sh/chart: grafana-6.49.0
  name: grafana
  namespace: default
  resourceVersion: "933445"
  uid: eefb9039-1a0b-42a2-93f4-b00202952b4d
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: grafana
      app.kubernetes.io/name: grafana
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        checksum/config: a2595b85e18556bc0de1f2f372e9e359553d9ae9bd18508e1a0084f27c7feb38
        checksum/dashboards-json-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
        checksum/sc-dashboard-provider-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
        checksum/secret: 1ea061ca428873f84f692fc1dfc086f12326157440acf50b5acfd7b25b711037
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: grafana
        app.kubernetes.io/name: grafana
    spec:
      automountServiceAccountToken: true
      containers:
      - env:
        - name: GF_SECURITY_ADMIN_USER
          valueFrom:
            secretKeyRef:
              key: admin-user
              name: grafana
        - name: GF_SECURITY_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              key: admin-password
              name: grafana
        - name: GF_PATHS_DATA
          value: /var/lib/grafana/
        - name: GF_PATHS_LOGS
          value: /var/log/grafana
        - name: GF_PATHS_PLUGINS
          value: /var/lib/grafana/plugins
        - name: GF_PATHS_PROVISIONING
          value: /etc/grafana/provisioning
        image: grafana/grafana:9.3.1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 10
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTPS
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 30
        name: grafana
        ports:
        - containerPort: 3000
          name: grafana
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /api/health
            port: 3000
            scheme: HTTPS
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/grafana/grafana.ini
          name: config
          subPath: grafana.ini
        - mountPath: /var/lib/grafana
          name: storage
        - mountPath: /etc/grafana/certs/
          name: grafana-certs
          readOnly: true
      dnsPolicy: ClusterFirst
      enableServiceLinks: true
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 472
        runAsGroup: 472
        runAsUser: 472
      serviceAccount: grafana
      serviceAccountName: grafana
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          defaultMode: 420
          name: grafana
        name: config
      - name: grafana-certs
        secret:
          defaultMode: 420
          items:
          - key: tls.crt
            path: tls.crt
          - key: tls.key
            path: tls.key
          secretName: grafana-tls
      - emptyDir: {}
        name: storage

 

4. svc 수정

  • ports 정보를 80 에서 443 으로 변경
kubectl edit svc grafana

------
  ports:
  - name: service
    port: 443
    protocol: TCP
    targetPort: 3000
------

 


 

 

 

 

 

 

Keycloak SSL [ keycloak 에 인증서 직접 부여]


1. 인증에 사용할 crt / key 파일은 secret 파일로 생성

2. Statefulset 수정 

apiVersion: apps/v1
kind: StatefulSet
metadata:
  annotations:
    meta.helm.sh/release-name: keycloak
    meta.helm.sh/release-namespace: default
  creationTimestamp: "2023-01-07T08:55:19Z"
  generation: 11
  labels:
    app.kubernetes.io/instance: keycloak
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: keycloak
    app.kubernetes.io/version: latest
    helm.sh/chart: keycloak-18.4.0
  name: keycloak
  namespace: default
  resourceVersion: "22219"
  uid: fbe91bf4-e242-4848-89dc-bffb402512ba
spec:
  podManagementPolicy: Parallel
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: keycloak
      app.kubernetes.io/name: keycloak
  serviceName: keycloak-headless
  template:
    metadata:
      annotations:
        checksum/config-startup: 7a33485f722479daf33e6401e30c167baa16006e262f9ec19b58100bb4e722c4
        checksum/secrets: 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a
      creationTimestamp: null
      labels:
        app.kubernetes.io/instance: keycloak
        app.kubernetes.io/name: keycloak
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app.kubernetes.io/component
                  operator: NotIn
                  values:
                  - test
                matchLabels:
                  app.kubernetes.io/instance: keycloak
                  app.kubernetes.io/name: keycloak
              topologyKey: failure-domain.beta.kubernetes.io/zone
            weight: 100
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app.kubernetes.io/component
                operator: NotIn
                values:
                - test
              matchLabels:
                app.kubernetes.io/instance: keycloak
                app.kubernetes.io/name: keycloak
            topologyKey: kubernetes.io/hostname
      containers:
      - env:
        - name: DB_VENDOR
          value: mariadb
        - name: DB_ADDR
          value: {IP입력}
        - name: DB_PORT
          value: "3306"
        - name: DB_DATABASE
          value: keycloak
        - name: DB_USER
          value: keycloak
        - name: DB_PASSWORD
          value: {Passwd}
        - name: KEYCLOAK_USER
          value: admin
        - name: KEYCLOAK_PASSWORD
          value: admin
        - name: KC_HTTPS_CERTIFICATE_KEY_FILE
          value: /ect/x509/https/tls.key
        - name: KC_HTTPS_CERTIFICATE_FILE
          value: /ext/x509/https/tls.crt
        - name: KC_HTTPS_PROTOCOLS
          value: TLSv1.3
        - name: KC_HTTP_PORT
          value: "8080"
        - name: KC_HTTPS_PORT
          value: "8443"
        - name: KC_HOSTNAME
          value: keycloak1.kgmarket.net
        image: jboss/keycloak:latest
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /auth/
            port: http
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: keycloak
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 9990
          name: http-management
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /auth/realms/master
            port: http
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        securityContext:
          runAsNonRoot: true
          runAsUser: 1000
        startupProbe:
          failureThreshold: 60
          httpGet:
            path: /auth/
            port: http
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 1
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /opt/jboss/startup-scripts/keycloak.cli
          name: startup
          readOnly: true
          subPath: keycloak.cli
        - mountPath: /etc/x509/https/
          name: keycloal-cert
          readOnly: true
      dnsPolicy: ClusterFirst
      enableServiceLinks: true
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 1000
      serviceAccount: keycloak
      serviceAccountName: keycloak
      terminationGracePeriodSeconds: 60
      volumes:
      - configMap:
          defaultMode: 365
          items:
          - key: keycloak.cli
            path: keycloak.cli
          name: keycloak-startup
        name: startup
      - name: keycloal-cert
        secret:
          defaultMode: 420
          items:
          - key: tls.crt
            path: tls.crt
          - key: tls.key
            path: tls.key
          secretName: keycloal-tls
  updateStrategy:
    type: RollingUpdate
status:
  availableReplicas: 1
  collisionCount: 0
  currentReplicas: 1
  currentRevision: keycloak-689d878b78
  observedGeneration: 11
  readyReplicas: 1
  replicas: 1
  updateRevision: keycloak-689d878b78
  updatedReplicas: 1

3. SVC 설정 확인

apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: keycloak
    meta.helm.sh/release-namespace: default
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  creationTimestamp: "2023-01-07T08:55:19Z"
  finalizers:
  - service.kubernetes.io/load-balancer-cleanup
  labels:
    app.kubernetes.io/component: http
    app.kubernetes.io/instance: keycloak
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: keycloak
    app.kubernetes.io/version: latest
    helm.sh/chart: keycloak-18.4.0
  name: keycloak-http
  namespace: default
  resourceVersion: "17158"
  uid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: xxxxxx
  clusterIPs:
  - xxxxxxxxx
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    nodePort: 31096
    port: 80
    protocol: TCP
    targetPort: 8080
  - name: https
    nodePort: 31097
    port: 443
    protocol: TCP
    targetPort: 8443
  - name: http-management
    nodePort: 31886
    port: 9990
    protocol: TCP
    targetPort: http-management
  selector:
    app.kubernetes.io/instance: keycloak
    app.kubernetes.io/name: keycloak
  sessionAffinity: None
  type: LoadBalancer

 

3. 접속 확인

 

+ Recent posts