k8s資源對象(二)

Configmap和Secret資源介紹

secret和configmap資源都是通過掛載的方式將對應數據掛載到容器內部環境中去使用,兩者的使用沒有太多的不同 ,configmap資源通常用於爲pod提供配置文件;secret資源主要用於爲pod提供證書、用戶名密碼等敏感數據;

configmap資源

Configmap將非機密性信息(如配置信息)和鏡像解耦, 實現方式爲將配置信息放到configmap對象中,然後在pod的中作爲Volume掛載到pod中,從而實現導入配置的目的。

ConfigMap資源使用場景

  • 通過Configmap給pod中的容器服務提供配置文件,配置文件以掛載到容器的形式使用。
  • 通過Configmap給pod定義全局環境變量。
  • 通過Configmap給pod傳遞命令行參數,如mysql -u -p中的賬戶名密碼可以通過Configmap傳遞。

注意事項

  • Configmap需要在pod使用它之前創建。
  • pod只能使用位於同一個namespace的Configmap,即Configmap不能跨namespace使用。
  • 通常用於非安全加密的配置場景。
  • Configmap通常是小於1MB的配置。

secret資源

Secret 的功能類似於 ConfigMap給pod提供額外的配置信息,但是Secret是一種包含少量敏感信息例如密碼、令牌或密鑰的對象。Secret 的名稱必須是合法的 DNS 子域名。每個Secret的大小最多爲1MiB,主要是爲了避免用戶創建非常大的Secret進而導致API服務器和kubelet內存耗盡,不過創建很多小的Secret也可能耗盡內存,可以使用資源配額來約束每個名字空間中Secret的個數。在通過yaml文件創建secret時,可以設置data或stringData字段,data和stringData字段都是可選的,data字段中所有鍵值都必須是base64編碼的字符串,如果不希望執行這種 base64字符串的轉換操作,也可以選擇設置stringData字段,其中可以使用任何非加密的字符串作爲其取值。

Secret資源使用流程

首先用戶向apiserver提交創建secret資源的請求;apiserver收到用戶的資源創建請求,通過apiserver的認證授權、准入控制後,apiserver會將創建好的secret信息存放在etcd中;隨後用戶在創建pod中調用了掛載某個secret以後,對應在pod創建時會被pause容器將對應secret資源中的data數據加載至對應pod中,從而實現讓向pod內部傳遞敏感數據的目的;

Secret資源使用場景

  • 作爲掛載到一個或多個容器上的卷 中的文件(crt文件、key文件)。
  • 作爲容器的環境變量。
  • 由 kubelet 在爲 Pod 拉取鏡像時使用(與鏡像倉庫的認證)。

Secret資源類型簡介

Kubernetes默認支持多種不同類型的secret,用於一不同的使用場景,不同類型的secret的配置參數也不一樣。

configmap資源使用示例

基於configmap給nginx pod提供自定義的server配置

1.1、創建configmap資源

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  mysite: |
    server {
       listen       80;
       server_name  www.mysite.com;
       index        index.html index.php index.htm;

       location / {
           root /data/nginx/mysite;
           if (!-e $request_filename) {
               rewrite ^/(.*) /index.html last;
           }
       }
    }

  myserver: |
    server {
       listen       80;
       server_name  www.myserver.com;
       index        index.html index.php index.htm;

       location / {
           root /data/nginx/myserver;
           if (!-e $request_filename) {
               rewrite ^/(.*) /index.html last;
           }
       }
    }  

data字段中的mysite和myserver是用來標識不同配置信息的,即該名稱用於pod掛載configmap資源時被引用的名稱;

應用資源配置清單

kubectl apply -f nginx-configmap-demo.yaml

驗證configmap資源

kubectl get cm

kubectl describe cm nginx-config  

1.2、創建pod使用使用掛載configmap

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ng-deploy-80
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.ik8s.cc/baseimages/nginx:1.20.0
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /data/nginx/mysite
          name: nginx-mysite-statics
        - mountPath: /data/nginx/myserver
          name: nginx-myserver-statics
        - name: nginx-mysite-config
          mountPath:  /etc/nginx/conf.d/mysite/
        - name: nginx-myserver-config
          mountPath:  /etc/nginx/conf.d/myserver/
      volumes:
      - name: nginx-mysite-config
        configMap:
          name: nginx-config
          items:
             - key: mysite
               path: mysite.conf
      - name: nginx-myserver-config
        configMap:
          name: nginx-config
          items:
             - key: myserver
               path: myserver.conf
      - name: nginx-myserver-statics
        nfs:
          server: 192.168.0.42
          path: /data/k8sdata/myserver
      - name: nginx-mysite-statics
        nfs:
          server: 192.168.0.42
          path: /data/k8sdata/mysite

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30019
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

上述配置清單主要定義了一個deploy類型的控制器和nodeport類型的service,其中deploy控制器定義了一個nginx pod 掛載使用nfs服務上的靜態資源和掛載使用configmap給nginx提供配置;service主要定義了通過標籤選擇器來匹配pod來實現將用戶請求的流量轉發至後端nginx pod;

在nfs服務器上準備靜態資源目錄

在nfs服務器上創建靜態資源

應用配置清單創建pod使用configmap資源和掛載nfs服務器上的靜態資源

kubectl apply -f nginx-dep-demo.yaml

驗證,查看pod配置信息是否正常被pod掛載?

可以看到pod正常掛載configmap中指定的配置信息;

在k8s集羣節點任意節點上修改hosts文件來解析域名

在k8s的節點上將對應域名指向集羣任意節點地址上即可

訪問nginx,看看對應nfs靜態資源是否能夠正常被訪問到?

這裏雖然能夠正常被訪問nginx主頁,但是不是我們想要的頁面,這其中的原因是,我們把nginxpod的配置文件掛載的路徑沒有在nginx.conf中導入,導致我們掛載的配置在nginx中沒有生效;

解決辦法

  • 進入pod內部,修改nginx.conf配置文件 (臨時生效,pod重建失效,不推薦)
  • 在製作鏡像時,直接將主配置文件寫好,再製作好鏡像;(推薦)
  • 使用configmap資源將導入nginx配置再此掛載至/etc/nginx/conf.d/目錄下;(默認nginx只導入了/etc/nginx/conf.d/*.conf,我們只需要將導入配置以.conf結尾的配置文件掛載至/etc/nginx/conf.d/目錄下即可)

進入nginxpod,修改主配置文件

這裏主要加上導入/etc/nginx/conf.d/下子目錄下的.conf結尾的配置文件,讓/etc/nginx/conf.d/myserver/myserver.conf和/etc/nginx/conf.d/mysite/mysite.conf配置文件被nginx加載;

驗證:使用不同域名訪問nginx看看是否能夠訪問到對應不同的靜態資源?

現在使用不同域名的方式訪問nginx就可以訪問到不同站點的資源了;生產中會通過前端一個負載均衡器來反向代理nodeport類型的service;

基於configmap給pod提供自定義環境變量

1.1、創建configmap資源

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  host: "172.31.7.189"
  username: "user1"
  password: "12345678"

應用上述配置清單,創建configmap資源

1.2、創建pod使用configmap資源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ng-deploy-80
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.ik8s.cc/baseimages/nginx:1.20.0
        env:
        - name: HOST
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: host
        - name: USERNAME
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: username
        - name: PASSWORD
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: password
        ######
        - name: "password"
          value: "123456"
        ports:
        - containerPort: 80

向pod內部傳遞環境變量的方式有兩種,一種是通過env字段來引用configmap資源,使用name字段來指定環境變量名稱,使用valueFrom字段來指定對應環境變量值的來源;configMapKeyRef字段表示使用configmap資源來向對應環境變量賦值;name是指定configmap的名稱,key是用來指定configmap中對應key;另外一種就是使用env字段,通過列表的方式直接向pod傳遞鍵值環境變量;

應用配置清單

可以看到創建的pod內部有我們再configmap中定義的環境變量,也有我們通過env直接指定鍵值的環境變量;

secret資源使用示例

基於自定義的Secret實現Nginx https認證

1、自簽名證書製作

1.1、生成自簽名CA證書

openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.ca.com'

1.2、生成自簽名證書私鑰和CSR

openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=www.mysite.com'

1.3、用自簽名CA證書籤發自簽名證書csr生成自簽名證書crt

openssl x509 -req -sha256 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

2、基於自簽名證書在k8s上創建secret資源

kubectl create secret tls myserver-tls-key --cert=./server.crt --key=./server.key

3、創建nginx配置清單使用secret

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
 default: |
    server {
       listen       80;
       server_name  www.mysite.com;
       listen 443 ssl;
       ssl_certificate /etc/nginx/conf.d/certs/tls.crt;
       ssl_certificate_key /etc/nginx/conf.d/certs/tls.key;

       location / {
           root /usr/share/nginx/html; 
           index index.html;
           if ($scheme = http ){  #未加條件判斷,會導致死循環
              rewrite / https://www.mysite.com permanent;
           }  

           if (!-e $request_filename) {
               rewrite ^/(.*) /index.html last;
           }
       }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myserver-myapp-frontend-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myserver-myapp-frontend
  template:
    metadata:
      labels:
        app: myserver-myapp-frontend
    spec:
      containers:
      - name: myserver-myapp-frontend
        image: harbor.ik8s.cc/baseimages/nginx:1.20.0
        ports:
          - containerPort: 80
        volumeMounts:
          - name: nginx-config
            mountPath:  /etc/nginx/conf.d/myserver
          - name: myserver-tls-key
            mountPath:  /etc/nginx/conf.d/certs
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
          items:
             - key: default
               path: mysite.conf
      - name: myserver-tls-key
        secret:
          secretName: myserver-tls-key 


---
apiVersion: v1
kind: Service
metadata:
  name: myserver-myapp-frontend
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30018
    protocol: TCP
  - name: htts
    port: 443
    targetPort: 443
    nodePort: 30019
    protocol: TCP
  selector:
    app: myserver-myapp-frontend 

上述配置清單主要創建了一個configmap資源,用來給nginxpod提供配置信息,然後創建了一個deploy控制器運行了一個nginx pod ,這個pod掛載使用configmap和secret資源;最後創建了一個service將對應nginx Pod服務暴露給集羣外部客戶端訪問;

應用配置清單

驗證:進入pod內部,查看對應配置信息和證書文件是否正常掛載?

可以看到我們創建configmap資源中的配置信息和secret資源中的證書信息都正常掛載至nginx pod對應指定目錄下

修改nginx主配置文件,讓其加載我們通過configmap掛載的配置文件

重載nginx pod配置文件

上述方法不推薦,正確的做法就是在打鏡像的時候,將對應配置文件打入鏡像;或者我們使用configmap將對應配置信息創建爲configmap資源對象,然後再pod中掛載對應配置信息即可;

驗證:訪問集羣任意節點30018端口和30019端口,看看對應nginx pod是否能夠正常被訪問?是否是加密訪問呢?

從上面的訪問情況可以看到,直接訪問30019,會報400,這是因爲30019時一個https的端口,用http的協議去訪問肯定不能正常響應;當我們訪問30018時,對應頁面會進行跳轉到https://www.mysite.com,這是因爲我們在nginx的配置中配置了訪問http端口進行重定向https://www.mysite.com;訪問30019端口時,用https協議訪問30019時,也正常加載了證書;

使用configmap將nginx配置信息導入主配置文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: include-conf
data:
 include.conf: |
    include /etc/nginx/conf.d/*/*.conf;
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
 default: |
    server {
       listen       80;
       server_name  www.mysite.com;
       listen 443 ssl;
       ssl_certificate /etc/nginx/conf.d/certs/tls.crt;
       ssl_certificate_key /etc/nginx/conf.d/certs/tls.key;

       location / {
           root /usr/share/nginx/html; 
           index index.html;
           if ($scheme = http ){  #未加條件判斷,會導致死循環
              rewrite / https://www.mysite.com permanent;
           }  

           if (!-e $request_filename) {
               rewrite ^/(.*) /index.html last;
           }
       }
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myserver-myapp-frontend-deployment-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myserver-myapp-frontend-v1
  template:
    metadata:
      labels:
        app: myserver-myapp-frontend-v1
    spec:
      containers:
      - name: myserver-myapp-frontend-v1
        image: harbor.ik8s.cc/baseimages/nginx:1.20.0
        ports:
          - containerPort: 80
        volumeMounts:
          - name: nginx-config
            mountPath:  /etc/nginx/conf.d/myserver
          - name: myserver-tls-key
            mountPath:  /etc/nginx/conf.d/certs
          - name: include-conf
            mountPath: /etc/nginx/conf.d
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
          items:
             - key: default
               path: mysite.conf
      - name: myserver-tls-key
        secret:
          secretName: myserver-tls-key 
      - name: include-conf
        configMap:
          name: include-conf
          items:
             - key: include.conf
               path: include.conf
---
apiVersion: v1
kind: Service
metadata:
  name: myserver-myapp-frontend-v1
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 31080
    protocol: TCP
  - name: htts
    port: 443
    targetPort: 443
    nodePort: 31443
    protocol: TCP
  selector:
    app: myserver-myapp-frontend-v1

pod掛載使用configmap時,對應pod內部必須事先不存在對應文件,如果對應文件存在,則對應pod會啓不起來;所以我們掛載configmap時指定掛載至/etc/nginx/conf.d即可;

應用配置清單,看看使用https訪問31443是否可以正常訪問?


基於自定義的Secret實現私有鏡像的下載認證

創建secret資源

方式一:通過命令創建

kubectl create secret docker-registry harbor.ik8s.cc-imagepull \
                                    --docker-server=harbor.ik8s.cc \
                                    --docker-username=admin \
                                    --docker-password=123456

方式二:通過docker/containerd認證文件創建

登錄harbor,生成config.json文件

使用config.json文件創建secret資源

kubectl create secret generic harbor.k8s.cc-registry-image-pull-key \
                --from-file=.dockerconfigjson=/root/.docker/config.json \
                --type=kubernetes.io/dockerconfigjson

在harbor上將baseimgaes倉庫設置爲私有倉庫

驗證,使用docker/containerd拉取harbor.k8s.cc/baseimages下的鏡像,看看是否可以正常拉取?

可以看到現在更改倉庫爲私有倉庫以後,對應倉庫中的鏡像不可以正常被拉取

驗證,使用私有倉庫鏡像創建pod,看看pod是否能夠正常運行起來?

apiVersion: v1
kind: Pod
metadata:
  name: "tomcat-demo"
  namespace: default
  labels:
    app: "tomcat-demo"
spec:
  containers:
  - name: tomcat-demo
    image: "harbor.ik8s.cc/baseimages/tomcat:v1"
    ports:
    - containerPort:  8080
      name:  http

應用配置清單,看看對應pod是否能夠正常跑起來?

可以看到對應pod處於ErrImagePull狀態,該狀態就是表示pod在創建時,下載鏡像錯誤

查看pod詳細信息

創建pod使用secret

apiVersion: v1
kind: Pod
metadata:
  name: "tomcat-demo"
  namespace: default
  labels:
    app: "tomcat-demo"
spec:
  containers:
  - name: tomcat-demo
    image: "harbor.ik8s.cc/baseimages/tomcat:v1"
    imagePullPolicy: Always
    ports:
    - containerPort:  8080
      name:  http
  imagePullSecrets:
    - name: harbor.k8s.cc-registry-image-pull-key

spec字段中使用imagePullSecrets字段來引用dockerconfigjson類型的secret資源,使用name字段指定secret的名稱即可

驗證pod運行狀態

應用配置清單,看看對應pod是否能夠正常跑起來?

可以看到現在對應pod正常跑起來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章