반응형

 

ConfigMap general file volume mount

kubectl create configmap test-file --from-file test.tar -n test

 

apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: test
spec:
  containers:
  - image: ...
    name: ...
    volumeMounts:
    - mountPath: /usr/share/test.tar
      subPath: test.tar
      name: filetest
  volumes:
  - name: filetest
    configMap:
      name: test-file

 

반응형
반응형

 

kubernetes dashboard를 설치하게 되면 기본적으로 kong proxy pod가 생성되면서,

이 kong proxy를 통해 사용하게되는데, 이를 비활성화하고 따로 ingress 적용을 통해 kubernetes dashboard에 접속하고

사용할 수 있다.

 

일반 ingress 적용 가이드 -

2024.10.22 - [Develop/k8s] - kubernetes dashboard ingress 연결 방법

 

1. 설치시 kong proxy disabled

helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
--create-namespace --namespace kubernetes-dashboard \
--set kong.enabled=false

 

 

2. ingress 적용

아래 URL과 service 조회를 통해 ingress를 생성한다

https://github.com/kubernetes/dashboard/blob/master/hack/gateway/prod.kong.yml

kubectl get svc -n kubernetes-dashboard
NAME                                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes-dashboard-api               ClusterIP   10.106.25.34     <none>        8000/TCP   6m13s
kubernetes-dashboard-auth              ClusterIP   10.101.168.28    <none>        8000/TCP   6m13s
kubernetes-dashboard-metrics-scraper   ClusterIP   10.104.27.35     <none>        8000/TCP   6m13s
kubernetes-dashboard-web               ClusterIP   10.109.176.153   <none>        8000/TCP   6m13s

 

dashboard ui에 로그인하기위해선 tls 적용이 필요하다.

Kubernetes Dashboard 아래 소스를 보면 setTokenCookie 부분이 있는데, 이 부분 때문에 tls가 필요해보인다.
아님말고...?
dashboard-master/modules/web/src/common/services/global/authentication.ts
---
private setTokenCookie_(token: string): void { if (this.isCurrentProtocolSecure_()) { this.cookies_.set(this.config_.authTokenCookieName, token, null, null, null, true, 'Strict'); return; } if (this.isCurrentDomainSecure_()) { this.cookies_.set(this.config_.authTokenCookieName, token, null, null, location.hostname, false, 'Strict'); } }
---

 

tls 적용을 위한 인증서 및 secret 생성

# 인증서 생성
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"

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

 

ingress 생성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ingressClassName: nginx
  rules:
  - host: dashboard.wky.kr
    http:
      paths:
      - path: /api/v1/login
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-auth
            port:
              number: 8000
      - path: /api/v1/csrftoken/login
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-auth
            port:
              number: 8000
      - path: /api/v1/me
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-auth
            port:
              number: 8000
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-api
            port:
              number: 8000
      - path: /metrics
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-api
            port:
              number: 8000
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard-web
            port:
              number: 8000
  tls:
  - hosts:
    - dashboard.wky.kr
    secretName: tls-dashboard

 

 

3. 로그인테스트를 위한 계정 및 토큰 발급

계정생성

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

 

토큰발급

kubectl -n kubernetes-dashboard create token admin-user

 

 

4. 로그인 및 확인

tls 적용을 했으므로 반드시 https로 접속 후 테스트한다.

반응형
반응형

 

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/

반응형
반응형

 

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

반응형
반응형

Containerd 에서 인증서 에러 발생시 인증서가 있는 경우와 없는 경우 설정하는 방법이다.

 

참고로 containerd 를 설정했다고 ctr 명령어 까지 같이 적용되는건 아니다. crictl 만 적용된다.

ctr 의  경우 인증서가 있으면 --tlscacert, --tlscrt, --tlskey 3개옵션을 적용하여 사용하면 되며

인증서가 없을 경우 --skip-verify 옵션을 사용하면된다.

 

1. containerd 설정파일을 수정한다.

$ vi /etc/containerd/config.toml

[plugins."io.containerd.grpc.v1.cri".registry]
   config_path = "/etc/containerd/certs.d"

 

2. certs.d 폴더를 생성한다.

$ cd /etc/containerd/

$ mkdir certs.d

 

3. 내부에 인증서 연결할 서버 폴더생성

$ cd certs.d

$ mkdir registry.wky.kr

$ cd registry.wky.kr

$ pwd
/etc/containerd/certs.d/registry.wky.kr

 

 

4. hosts.toml 파일 생성 

인증서가 있는 경우.

$ vi hosts.toml

server = "https://registry.wky.kr"

[host."https://registry.wky.kr"]
  capabilities = ["pull", "resolve"]
  # pemfile 이 있는 경로 및 파일 입력
  ca = pemfile.pem
  # crt, key, pem 파일이 있는 경로 및 파일 입력
  client = [[crtfile.crt, keyfile.key], [pemfile.pem]]

 

인증서가 없는 경우

$ vi hosts.toml

server = "https://registry.wky.kr"

[host."https://registry.wky.kr"]
  capabilities = ["pull", "resolve"]
  skip_verify = true

 

 

 

참고 : https://github.com/containerd/containerd/blob/main/docs/hosts.md

반응형
반응형

 

Container 실행없이 이미지 내에 있는 파일들을 확인하는 방법이다.

'ctr image mount imagename:tag 폴더' 명렁어를 통해 확인할 수 있다.

 

먼저 이미지가 서버 내에 있어야함.

$ crictl images
IMAGE                                    TAG                 IMAGE ID            SIZE
docker.io/library/busybox                latest              63cd0d5fb10d7       1.86MB

$ mkdir busybox

$ ctr -n=k8s.io image mount docker.io/library/busybox:latest ./busybox/
sha256:66ccab9b46d8f9daffd6e24c69ab2d6c5a5b44e9d0e39991985a910a2775755e
./busybox/

$ ls busybox/
bin  dev  etc  home  lib  lib64  root  tmp  usr  var

 

반응형
반응형

 

간단하게 인증서 설정없이 Docker Private Registry를 k8s에 설치하는 방법이다. 설치 후 UI 적용할 예정.

 

1. id, password 생성 (굳이 안 해도 됨)

 nerdctl run --entrypoint htpasswd   httpd:2 -Bbn testuser testpassword > auth/htpasswd

 

 

2. namespace 생성 및 secret 생성

$ kubectl create ns registry
$ kubectl create secret generic registry-auth --from-file=idpass=./htpasswd -n registry

 

 

3. pv, pvc, deployment, service 생성

storageclass가 없을 경우 pv를 생성하고 workernode에 registry폴더를 생성한다.(해당 경로는 적절히 수정해서 사용하면 됨)

1번에 id, password 생성 하지 않았으면, deployment 내 registry-auth 부분들 삭제하고 진행

아래 yaml 생성 후 kubectl apply -f registry.yaml -n registry 명령어 실행

$ vi registry.yaml
$ kubectl apply -f registry.yaml -n registry

apiVersion: v1
kind: PersistentVolume
metadata:
  name: registry-pv
  labels:
    reg: registry
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: "/root/registry"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: registry-pvc
  labels:
    reg: registry
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      reg: registry
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry
  labels:
    reg: registry
spec:
  replicas: 1
  selector:
    matchLabels:
      reg: registry
  template:
    metadata:
      labels:
        reg: registry
    spec:
      containers:
      - name: registry
        image: registry:2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000
        volumeMounts:
        - name: registry-auth
          mountPath: /auth # 이미지 내 기본 registry auth 경로
        - name: registry-data
          mountPath: /var/lib/registry
        env:
        - name: REGISTRY_AUTH_HTPASSWD_PATH # 기본 설정
          value: /auth/idpass # secert에 들어가는 파일을 idpass로 생성
        - name: REGISTRY_AUTH_HTPASSWD_REALM # 기본 설정
          value: "Registry Realm"
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
      volumes:
      - name: registry-auth
        secret:
          secretName: registry-auth
      - name: registry-data
        persistentVolumeClaim:
          claimName: registry-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: registry
spec:
  type: NodePort
  ports:
    - port: 5000
      targetPort: 5000
      nodePort: 30050
      protocol: TCP
  selector:
    reg: registry

 

 

4. 테스트

curl localhost:30050/v2/_catalog -u "testuser:testpassword"

 

 

5. UI 적용 (UI가 굳이 필요없으면 안 해도 됨)

UI 는 아래 오픈소스를 사용할 예정이다.

https://github.com/Joxit/docker-registry-ui

 

우선 위에 생성한 registry 에 ingress 를 등록해야한다. (Domain이 일치해야 UI에서 인증을 사용할 수 있음.)

$ vi registry-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: registry
  nginx.ingress.kubernetes.io/proxy-body-size: 4096m # 이미지 업로드 용량으로 반드시 설정필요하며 필요에 따라 설정
spec:
  ingressClassName: nginx
  rules:
  - host: registry.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: registry
            port:
              number: 5000

 

또한, 위에 생성한 Deployment에 환경변수를 추가해야한다.

  $ kubectl edit deploy -n registry registry
  ...
      - env:
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin # 추가
          value: '[http://registry-ui.wky.kr:30080]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods # 추가
          value: '[HEAD,GET,OPTIONS,DELETE]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials # 추가
          value: '[true]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers # 추가
          value: '[Authorization,Accept]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers # 추가
          value: '[Docker-Content-Digest]'
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
        - name: REGISTRY_AUTH_HTPASSWD_PATH
          value: /auth/idpass
        - name: REGISTRY_AUTH_HTPASSWD_REALM
          value: Registry Realm     
  ...

 

UI 설치

특히 아래 yaml의 NGINX_PROXY_PASS_URL은 k8s service domain을 넣거나 nodeport를 넣거나 ingress를 넣어주면된다.

$ vi registry-ui.yaml
$ kubectl apply -f registry-ui -n registry

apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry-ui
  labels:
    reg: registry-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      reg: registry-ui
  template:
    metadata:
      labels:
        reg: registry-ui
    spec:
      containers:
      - name: registry-ui
        image: joxit/docker-registry-ui:main
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        env:
        - name: SINGLE_REGISTRY
          value: "true"
        - name: REGISTRY_TITLE
          value: Docker Registry UI
        - name: DELETE_IMAGES
          value: "true"
        - name: SHOW_CONTENT_DIGEST
          value: "true"
        - name: SHOW_CATALOG_NB_TAGS
          value: "true"
        - name: CATALOG_MIN_BRANCHES
          value: "1"
        - name: CATALOG_MAX_BRANCHES
          value: "1"
        - name: TAGLIST_PAGE_SIZE
          value: "100"
        - name: REGISTRY_SECURED
          value: "true"
        - name: CATALOG_ELEMENTS_LIMIT
          value: "1000"
        - name: NGINX_PROXY_PASS_URL
          value: http://registry.registry:5000 #  http://registry.wky.kr:30050 또는 http://registry.wky.kr:30080
        - name: REGISTRY_SECURED
          value: "true"
---
apiVersion: v1
kind: Service
metadata:
  name: registry-ui
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30051
      protocol: TCP
  selector:
    reg: registry-ui
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: registry-ui
spec:
  ingressClassName: nginx
  rules:
  - host: registry-ui.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: registry-ui
            port:
              number: 80

 

결과 확인

 

기타 : https 로 여는법

사설 인증서를 생성하고, 사설인증서이기 때문에 해당 registry를 실제 사용할 서버를 위해 ca파일도 생성한다.

# 사설 인증서 생성
$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -subj "/CN=registry.wky.kr" -addext "subjectAltName=DNS:registry.wky.kr" -x509 -days 365 -out domain.crt

# 이미지 push 또는 pull 위한 ca 파일 생성
$ cat domain.crt domain.key > domain.pem

 

registry에 마운트할 secret과 ingress에 등록할 secert 2개를 생성한다.

# registry 인증서용
$ kubectl create secret generic https-registry --from-file=domain.crt=./domain.crt --from-file=domain.key=./domain.key -n registry
 
# registry ingress용
$ kubectl create secret tls tls-registry --key ./domain.key --cert ./domain.crt -n registry

 

deployment와 service, ingress 수정

# deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry
  labels:
    reg: registry
spec:
  replicas: 1
  selector:
    matchLabels:
      reg: registry
  template:
    metadata:
      labels:
        reg: registry
    spec:
      containers:
      - name: registry
        image: registry:2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 443 # 443으로 수정
        volumeMounts:
        - name: registry-auth
          mountPath: /auth 
        - name: registry-data
          mountPath: /var/lib/registry
        - name: https-registry # 인증서파일 마운트
          mountPath: /tmp
        env:
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin
          value: '[http://registry-ui.wky.kr:30080]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods 
          value: '[HEAD,GET,OPTIONS,DELETE]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials 
          value: '[true]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers
          value: '[Authorization,Accept]'
        - name: REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers 
          value: '[Docker-Content-Digest]'
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
        - name: REGISTRY_AUTH_HTPASSWD_PATH
          value: /auth/idpass
        - name: REGISTRY_AUTH_HTPASSWD_REALM
          value: Registry Realm     
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
        - nmae: REGISTRY_HTTP_TLS_CERTIFICATE # 인증서 설정
          value: /tmp/domain.crt
        - name: REGISTRY_HTTP_TLS_KEY  # 인증서 설정
          value: /tmp/domain.key
        - name: REGISTRY_HTTP_ADDR # 443으로 포트 열기
          value: 0.0.0.0:443
      volumes:
      - name: registry-auth
        secret:
          secretName: registry-auth
      - name: registry-data
        persistentVolumeClaim:
          claimName: registry-pvc
      - name: https-registry # 인증서 secret 마운트
        secret:
          secretName: https-registry
 
# serivce 
apiVersion: v1
kind: Service
metadata:
  name: registry
spec:
  type: ClusterIP # NodePort도 관계없음.
  ports:
    - port: 443 # 443으로 수정
      targetPort: 443  # 443으로 수정
      protocol: TCP
  selector:
    reg: registry
    
# ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: registry
  nginx.ingress.kubernetes.io/backend-protocol: HTTPS # HTTPS 통신
  nginx.ingress.kubernetes.io/proxy-body-size: 4096m 
spec:
  ingressClassName: nginx
  rules:
  - host: registry.wky.kr
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: registry
            port:
              number: 443
  tls: # tls secret 마운트
  - hosts:
    - registry.wky.kr
  secretName: tls-registry

 

 

참고 : 

https://distribution.github.io/distribution/

https://github.com/Joxit/docker-registry-ui

 

반응형
반응형

 

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

 

 

반응형

+ Recent posts