सीक्रेट्स (Secrets) का उपयोग करके प्रमाण-पत्रों को सुरक्षित रूप से वितरित करें

यह पृष्ठ दिखाता है कि संवेदनशील डेटा जैसे कि पासवर्ड और एन्क्रिप्शन कुंजियाँ
पॉड्स (pods) में सुरक्षित रूप से कैसे इंजेक्ट की जाती हैं।

शुरू करने से पहले

आपको कुबरनेट्स क्लस्टर की ज़रूरत पड़ेगी और क्यूब सीटीएल कमांड लाइन साधन को समनुरूप करना होगा ताकि वो आपके क्लस्टर के साथ संवाद कर सकें। हमारी सलाह है की इस टुटोरिअल को क्लस्टर में रन करने के लिए कम से कम दो नोड का इस्तेमाल करे जो कि कंट्रोल प्लेन होस्ट के तरह ना एक्ट करे। अगर आपके पास पहले से क्लस्टर नही है, आप minikube की मदद से वह बना सकते है या आप नीचे दिए हुए इन दो कुबरनेट्स प्लेग्राउंड का इस्तेमाल कर सकते हैं:

अपने गुप्त डेटा को base-64 रूपांतरण में बदलें

मान लीजिए कि आप दो गुप्त जानकारियाँ रखना चाहते हैं: एक उपयोगकर्ता नाम my-app
और एक पासवर्ड 39528$vdg7Jb। सबसे पहले, base64 एन्कोडिंग टूल का उपयोग करके अपने उपयोगकर्ता नाम और पासवर्ड को base-64 रूप में बदलें। नीचे दिए गए उदाहरण में सामान्य रूप से उपलब्ध base64 प्रोग्राम का उपयोग किया गया है:

echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64

आउटपुट दिखाता है कि आपके उपयोगकर्ता नाम का base-64 रूपांतरण है bXktYXBw, और पासवर्ड का base-64 रूपांतरण है Mzk1MjgkdmRnN0pi

एक सीक्रेट (Secret) बनाएँ

यहाँ एक कॉन्फ़िगरेशन फ़ाइल दी गई है जिसका उपयोग आप अपना उपयोगकर्ता नाम और पासवर्ड
रखने वाले सीक्रेट को बनाने के लिए कर सकते हैं:

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
data:
  username: bXktYXBw
  password: Mzk1MjgkdmRnN0pi
  1. सीक्रेट बनाएँ:

    kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
    
  2. सीक्रेट के बारे में जानकारी देखें:

    kubectl get secret test-secret
    

    आउटपुट:

    NAME          TYPE      DATA      AGE
    test-secret   Opaque    2         1m
    
  3. सीक्रेट के बारे में और विस्तृत जानकारी देखें:

    kubectl describe secret test-secret
    

    आउटपुट:

    Name:       test-secret
    Namespace:  default
    Labels:     <none>
    Annotations:    <none>
    
    Type:   Opaque
    
    Data
    ====
    password:   13 bytes
    username:   7 bytes
    

सीधे kubectl से एक सीक्रेट (Secret) बनाएँ

यदि आप Base64 एन्कोडिंग चरण को छोड़ना चाहते हैं,
तो आप उसी Secret को kubectl create secret कमांड का उपयोग करके बना सकते हैं। उदाहरण के लिए:

kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'

यह तरीका अधिक सुविधाजनक है। पहले दिखाया गया विस्तृत तरीका हर चरण को स्पष्ट रूप से चलाकर यह दर्शाता है कि अंदर क्या हो रहा है।

एक ऐसा पॉड बनाएँ जिसे वॉल्यूम (Volume) के माध्यम से सीक्रेट (Secret) डेटा तक पहुँच प्राप्त हो

यहाँ एक कॉन्फ़िगरेशन फ़ाइल दी गई है जिसका उपयोग आप एक पॉड बनाने के लिए कर सकते हैं:

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        # name must match the volume name below
        - name: secret-volume
          mountPath: /etc/secret-volume
          readOnly: true
  # The secret data is exposed to Containers in the Pod through a Volume.
  volumes:
    - name: secret-volume
      secret:
        secretName: test-secret
  1. पॉड बनाएँ:

    kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
    
  2. सुनिश्चित करें कि आपका पॉड चल रहा है:

    kubectl get pod secret-test-pod
    

    आउटपुट:

    NAME              READY     STATUS    RESTARTS   AGE
    secret-test-pod   1/1       Running   0          42m
    
  3. उस कंटेनरों के अंदर एक शेल खोलें जो आपके पॉड में चल रहा है:

    kubectl exec -i -t secret-test-pod -- /bin/bash
    
  4. सीक्रेट डेटा कंटेनरों को एक वॉल्यूम के माध्यम से उपलब्ध कराया जाता है जो /etc/secret-volume के अंतर्गत माउंट किया गया है।

    अपने शेल में, /etc/secret-volume डाइरेक्टरी में फ़ाइलों की सूची देखें:

    # यह कमांड कंटेनर के अंदर शेल में चलाएँ
    ls /etc/secret-volume
    

    आउटपुट दो फ़ाइलें दिखाता है, जो हर एक गुप्त डेटा के लिए होती हैं:

    password username
    
  5. अपने शेल में, username और password फ़ाइलों की सामग्री देखें:

    # यह कमांड कंटेनर के अंदर शेल में चलाएँ
    echo "$( cat /etc/secret-volume/username )"
    echo "$( cat /etc/secret-volume/password )"
    

    आउटपुट में आपका उपयोगकर्ता नाम और पासवर्ड दिखेगा:

    my-app
    39528$vdg7Jb
    

अपने इमेज या कमांड लाइन को इस प्रकार संशोधित करें कि प्रोग्राम mountPath डाइरेक्टरी में फ़ाइलों को ढूंढे। सीक्रेट की data मैप में हर कुंजी इस डाइरेक्टरी में एक फ़ाइल नाम बन जाती है।

सीक्रेट (Secret) कुंजियों को विशिष्ट फ़ाइल पथों पर प्रोजेक्ट करे

आप वॉल्यूम के अंदर उन पथों को भी नियंत्रित कर सकते हैं जहाँ सीक्रेट कुंजियाँ प्रोजेक्ट की जाएँ।
प्रत्येक कुंजी के लक्ष्य पथ को बदलने के लिए .spec.volumes[].secret.items फ़ील्ड का उपयोग करें:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

जब आप इस पॉड को डिप्लॉय करते हैं, तो निम्न होता है:

  • mysecret से username कुंजी कंटेनर में /etc/foo/username की बजाय /etc/foo/my-group/my-username पथ पर उपलब्ध होती है।
  • उस Secret ऑब्जेक्ट की password कुंजी प्रोजेक्ट नहीं की जाती है।

यदि आप .spec.volumes[].secret.items का उपयोग करके कुंजियों को स्पष्ट रूप से सूचीबद्ध करते हैं, तो निम्न बातों का ध्यान रखें:

  • केवल वही कुंजियाँ प्रोजेक्ट होती हैं जो items में निर्दिष्ट हैं।
  • यदि आप Secret की सभी कुंजियों का उपयोग करना चाहते हैं, तो सभी को items फ़ील्ड में सूचीबद्ध करना होगा।
  • सूचीबद्ध सभी कुंजियाँ संबंधित सीक्रेट में मौजूद होनी चाहिए। अन्यथा वॉल्यूम नहीं बनाया जाएगा।

सीक्रेट (Secret) कुंजियों के लिए POSIX अनुमतियाँ सेट करें

आप किसी एक सीक्रेट कुंजी के लिए POSIX फ़ाइल एक्सेस अनुमति बिट्स सेट कर सकते हैं।
यदि आप कोई अनुमति निर्दिष्ट नहीं करते हैं, तो डिफ़ॉल्ट रूप से 0644 उपयोग होती है।
आप पूरे सीक्रेट वॉल्यूम के लिए एक डिफ़ॉल्ट POSIX फ़ाइल मोड भी सेट कर सकते हैं,
और आवश्यकता होने पर किसी कुंजी के लिए उसे ओवरराइड कर सकते हैं।

उदाहरण के लिए, आप इस तरह डिफ़ॉल्ट मोड निर्दिष्ट कर सकते हैं:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 0400

Secret /etc/foo पर माउंट किया गया है; Secret वॉल्यूम माउंट द्वारा बनाई गई सभी फ़ाइलों की अनुमति 0400 होगी।

सीक्रेट (Secret) डेटा का उपयोग करके कंटेनर एनवायरनमेंट वेरिएबल परिभाषित करें

आप अपने कंटेनरों में सीक्रेट्स के डेटा को एनवायरनमेंट वेरिएबल्स के रूप में उपयोग कर सकते हैं।

यदि कोई कंटेनर पहले से ही एनवायरनमेंट वेरिएबल के रूप में सीक्रेट का उपयोग कर रहा है,
तो सीक्रेट अपडेट कंटेनर द्वारा तब तक नहीं देखा जाएगा जब तक कि कंटेनर को पुनः प्रारंभ (restart) न किया जाए। ऐसे कई थर्ड पार्टी समाधान उपलब्ध हैं जो सीक्रेट बदलने पर कंटेनर को पुनः प्रारंभ (restart) करते हैं।

किसी एक सीक्रेट (Secret) से डेटा के साथ कंटेनर एनवायरनमेंट वेरिएबल परिभाषित करें

  • सीक्रेट में key-value जोड़े के रूप में एक एनवायरनमेंट वेरिएबल परिभाषित करें:

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    
  • पॉड विनिर्देशन (specification) में SECRET_USERNAME नामक एनवायरनमेंट वेरिएबल को सीक्रेट में परिभाषित backend-username मान सौंपें।

    apiVersion: v1
    kind: Pod
    metadata:
      name: env-single-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
    
  • पॉड बनाएं:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
    
  • अपनी शेल में, कंटेनर एनवायरनमेंट वेरिएबल SECRET_USERNAME की सामग्री प्रदर्शित करें:

    kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
    

    आउटपुट इस प्रकार होगा:

    backend-admin
    

एक से अधिक सीक्रेट्स (Secrets) के डेटा से कंटेनर एनवायरनमेंट वेरिएबल्स परिभाषित करें

  • पहले के उदाहरण की तरह, पहले सीक्रेट्स बनाएं:

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    kubectl create secret generic db-user --from-literal=db-username='db-admin'
    
  • पॉड विनिर्देशन में एनवायरनमेंट वेरिएबल्स परिभाषित करें।

    apiVersion: v1
    kind: Pod
    metadata:
      name: envvars-multiple-secrets
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: BACKEND_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-user
              key: db-username
    
  • पॉड बनाएं:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
    
  • शेल में, कंटेनर एनवायरनमेंट वेरिएबल्स देखें:

    kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
    

    आउटपुट कुछ ऐसा होगा:

    DB_USERNAME=db-admin
    BACKEND_USERNAME=backend-admin
    

सीक्रेट (Secret) के सभी key-value जोड़ों को कंटेनर एनवायरनमेंट वेरिएबल्स के रूप में कॉन्फ़िगर करें

  • कई key-value जोड़ों के साथ सीक्रेट बनाएं:

    kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
    
  • envFrom का उपयोग करके सीक्रेट के सभी डेटा को कंटेनर एनवायरनमेंट वेरिएबल्स के रूप में परिभाषित करें। सीक्रेट में जो key है वह पॉड में एनवायरनमेंट वेरिएबल्स का नाम बन जाता है।

    apiVersion: v1
    kind: Pod
    metadata:
      name: envfrom-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        envFrom:
        - secretRef:
            name: test-secret
    
  • पॉड बनाएं:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
    
  • शेल में, username और password कंटेनर एनवायरनमेंट वेरिएबल्स प्रदर्शित करें:

    kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
    

    आउटपुट कुछ इस तरह होगा:

    username: my-app
    password: 39528$vdg7Jb
    

उदाहरण: सीक्रेट्स (Secrets) का उपयोग करके prod/test क्रेडेंशियल्स को Pods में उपलब्ध कराना

इस उदाहरण में एक पॉड प्रोडक्शन क्रेडेंशियल्स वाला सीक्रेट उपयोग करता है और दूसरा पॉड टेस्ट एनवायरनमेंट क्रेडेंशियल्स वाला सीक्रेट।

  1. प्रोड (prod) एनवायरनमेंट क्रेडेंशियल्स के लिए सीक्रेट बनाएं:

    kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
    

    आउटपुट:

    secret "prod-db-secret" created
    
  2. टेस्ट एनवायरनमेंट क्रेडेंशियल्स के लिए सीक्रेट बनाएं:

    kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
    

    आउटपुट:

    secret "test-db-secret" created
    
  3. पॉड manifests बनाएं:

    cat <<EOF > pod.yaml
    apiVersion: v1
    kind: List
    items:
    - kind: Pod
      apiVersion: v1
      metadata:
        name: prod-db-client-pod
        labels:
          name: prod-db-client
      spec:
        volumes:
        - name: secret-volume
          secret:
            secretName: prod-db-secret
        containers:
        - name: db-client-container
          image: myClientImage
          volumeMounts:
          - name: secret-volume
            readOnly: true
            mountPath: "/etc/secret-volume"
    - kind: Pod
      apiVersion: v1
      metadata:
        name: test-db-client-pod
        labels:
          name: test-db-client
      spec:
        volumes:
        - name: secret-volume
          secret:
            secretName: test-db-secret
        containers:
        - name: db-client-container
          image: myClientImage
          volumeMounts:
          - name: secret-volume
            readOnly: true
            mountPath: "/etc/secret-volume"
    EOF
    
  4. सभी ऑब्जेक्ट्स को API सर्वर पर लागू करें:

    kubectl create -f pod.yaml
    

दोनों कंटेनरों में निम्नलिखित फाइलें मौजूद होंगी जिनमें पर्यावरण अनुसार मान होंगे:

/etc/secret-volume/username
/etc/secret-volume/password

आप दो सर्विस अकाउंट्स का उपयोग करके पॉड विनिर्देशन को और सरल बना सकते हैं:

  1. prod-user जो prod-db-secret का उपयोग करता है
  2. test-user जो test-db-secret का उपयोग करता है

पॉड विनिर्देशन इस प्रकार सरल हो जाता है:

apiVersion: v1
kind: Pod
metadata:
  name: prod-db-client-pod
  labels:
    name: prod-db-client
spec:
  serviceAccount: prod-db-client
  containers:
  - name: db-client-container
    image: myClientImage

संदर्भ

आगे क्या है

  • Secrets के बारे में और जानें।
  • Volumes के बारे में जानकारी प्राप्त करें।