Skip to content

第10章 ingress 高可用-配置管理 configmap-secret

详解本章所讲内容:

10.1 Ingress-nginx-controller 代理 pod 流程回顾

10.2 通过 Ingress-nginx-Controller 实现按流量百分比代理 Pod

10.3 实战:Ingress-Nginx-controller 高可用

10.4 Configmap 基本介绍

10.5 Configmap 创建方法

10.6 使用 Configmap

10.7 Configmap 热更新

10.8 Secret 概述

注意:要把 istio 自动注入关掉:

$ kubectl label ns default istio-injection-

10.1 Ingress-nginx-controller 代理 pod 流程回顾

10.1.1 使用 Ingress Controller 代理 k8s 内部应用的流程

(1) 部署 Ingress-nginx- controller,我们 ingress controller 使用的是 nginx

(2) 创建 Pod 应用,可以通过控制器创建 pod

(3) 创建 Service,用来分组 pod

(4) 创建 Ingress http,测试通过 http 访问应用

(5) 创建 Ingress https,测试通过 https 访问应用

​ 使用七层负载均衡调度器 ingress controller 时,当客户端访问 kubernetes 集群内部的应用时, 数据包走向如下图流程所示:

img

10.2 实战:Ingress-Nginx-controller 高可用

$ kubectl delete -f deploy.yaml 
$ kubectl apply -f ingress-deploy.yaml

查看控制节点的污点

$ kubectl describe node k8s-master01 |grep -i taints

10.2.1 通过 keepalive+nginx 实现 nginx-ingress-controller 高可用

1、安装 nginx 主备:

控制节点工作节点 上做 nginx 主备安装

$ yum install epel-release nginx keepalived nginx-mod-stream -y 
$ yum install epel-release nginx keepalived nginx-mod-stream -y

2、修改 nginx 配置文件。主备一样

$ vim /etc/nginx/nginx.conf 
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

## 四层负载均衡,为两台Master apiserver组件提供负载均衡
stream {

    log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';

    access_log  /var/log/nginx/k8s-access.log  main;

    upstream nginx-ingress {
       server 192.168.2.201:80;  
       server 192.168.2.202:80;   
    }

    server {
       listen 30080; 
       proxy_pass nginx-ingress;
    }
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

}

注意:nginx 监听端口变成大于 30000 的端口,比方说 30080,这样访问域名就可以了,必须是满足大于 30000 以上,才能代理 ingress-controller

3、keepalive 配置

1)主keepalived

主keppalived配置文件

$ vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs { 
   notification_email { 
     acassen@firewall.loc 
     failover@firewall.loc 
     sysadmin@firewall.loc 
   } 
   notification_email_from Alexandre.Cassen@firewall.loc  
   smtp_server 127.0.0.1 
   smtp_connect_timeout 30 
   router_id NGINX_MASTER
} 

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 { 
    state MASTER 
    interface ens224  ## 修改为实际网卡名
    virtual_router_id 51 ## VRRP 路由 ID实例,每个实例是唯一的 
    priority 100    ## 优先级,备服务器设置 90 
    advert_int 1    ## 指定VRRP 心跳包通告间隔时间,默认1秒 
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    ## 虚拟IP
    virtual_ipaddress { 
        192.168.2.210/24
    } 
    track_script {
        check_nginx
    } 
}

#vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)
#virtual_ipaddress:虚拟IP(VIP)

nginx检测脚本

$ vim /etc/keepalived/check_nginx.sh 

#!/bin/bash
#1、判断Nginx是否存活
counter=`ps -C nginx --no-header | wc -l`
if [ $counter -eq 0 ]; then
    #2、如果不存活则尝试启动Nginx
    service nginx start
    sleep 2
    #3、等待2秒后再次获取一次Nginx状态
    counter=`ps -C nginx --no-header | wc -l`
    #4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
    if [ $counter -eq 0 ]; then
        service  keepalived stop
    fi
fi 

授予可执行权限

$ chmod +x /etc/keepalived/check_nginx.sh
2)备 keepalive

备keppalived配置文件

$ vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs { 
   notification_email { 
     acassen@firewall.loc 
     failover@firewall.loc 
     sysadmin@firewall.loc 
   } 
   notification_email_from Alexandre.Cassen@firewall.loc  
   smtp_server 127.0.0.1 
   smtp_connect_timeout 30 
   router_id NGINX_MASTER
} 

vrrp_script check_nginx {
    script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 { 
    state BACKUP 
    interface ens224  ## 修改为实际网卡名
    virtual_router_id 51 ## VRRP 路由 ID实例,每个实例是唯一的 
    priority 90    ## 优先级,备服务器设置 90 
    advert_int 1    ## 指定VRRP 心跳包通告间隔时间,默认1秒 
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    ## 虚拟IP
    virtual_ipaddress { 
        192.168.2.210/24
    } 
    track_script {
        check_nginx
    } 
}

#vrrp_script:指定检查nginx工作状态脚本(根据nginx状态判断是否故障转移)
#virtual_ipaddress:虚拟IP(VIP)

nginx检测脚本

$ vim /etc/keepalived/check_nginx.sh
#!/bin/bash
#1、判断Nginx是否存活
counter=`ps -C nginx --no-header | wc -l`
if [ $counter -eq 0 ]; then
    #2、如果不存活则尝试启动Nginx
    service nginx start
    sleep 2
    #3、等待2秒后再次获取一次Nginx状态
    counter=`ps -C nginx --no-header | wc -l`
    #4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
    if [ $counter -eq 0 ]; then
        service  keepalived stop
    fi
fi 

授予可执行权限

$ chmod +x /etc/keepalived/check_nginx.sh

注:keepalived 根据脚本返回状态码(0 为工作正常,非 0 不正常)判断是否故障转移。

4、启动服务:

$ systemctl daemon-reload
$ systemctl enable nginx keepalived 
$ systemctl start nginx
$ systemctl start keepalived

$ systemctl daemon-reload
$ systemctl enable nginx keepalived 
$ systemctl start nginx
$ systemctl start keepalived

5、测试 vip 是否绑定成功

主keepalived上存在VIP

$ ip addr |grep 192.168.2.210
    inet 192.168.2.210/24 scope global secondary ens224

6、测试 keepalived:

停掉主的keepalived,Vip 会漂移到备keepalived

$ systemctl stop keepalived
$ ip addr |grep 192.168.2.210

启动主的keepalived,Vip 又会漂移到 主的keepalived

$ systemctl start keepalived
$ ip addr |grep 192.168.2.210

10.2.2 实战:测试 Ingress HTTP 代理 k8s 内部站点

1、部署后端 tomcat 服务

$ vim ingress-demo.yaml

apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
    release: canary
  ports:
  - name: http
    targetPort: 8080
    port: 8080
  - name: ajp
    targetPort: 8009
    port: 8009
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tomcat
      release: canary
  template:
    metadata:
      labels:
        app: tomcat
        release: canary
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5.34-jre8-alpine 
        imagePullPolicy: IfNotPresent  
        ports:
        - name: http
          containerPort: 8080
          name: ajp
          containerPort: 8009

更新资源清单 yaml 文件:

$ kubectl apply -f ingress-demo.yaml 

查看 pod 是否部署成功

$ kubectl get pods -l app=tomcat
NAME                            READY   STATUS    RESTARTS   AGE
tomcat-deploy-b5f55d4c8-fmk62   1/1     Running   0          13s
tomcat-deploy-b5f55d4c8-mf84c   1/1     Running   0          13s

2、编写 ingress 规则

编写 ingress 的配置清单

$ vim ingress-myapp.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-myapp
  namespace: default
spec:
  ingressClassName: nginx
  rules:
  - host: tomcat.lucky.com
    http:
      paths:
      - path: /
        pathType:  Prefix
        backend:
         service:
           name: tomcat
           port:
            number: 8080
  rules:                    #定义后端转发的规则
  - host: tomcat.lucky.com  #通过域名进行转发
    http:
      paths:
      - path: /         #配置访问路径,如果通过 url 进行转发,需要修改;空默认为访问的路径为"/" 
        pathType:  Prefix
        backend:        #配置后端服务

更新 yaml 文件:

$ kubectl apply -f ingress-myapp.yaml 

查看 ingress-myapp 的详细信息

$ kubectl describe ingress ingress-myapp 
Name:             ingress-myapp
Labels:           <none>
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host              Path  Backends
  ----              ----  --------
  tomcat.lucky.com  
                    /   tomcat:8080 (10.244.58.248:8080,10.244.85.245:8080)
Annotations:        <none>
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  Sync    13s   nginx-ingress-controller  Scheduled for sync

3、访问测试

修改电脑本地的 host 文件,增加如下一行,ip 是 vip

192.168.2.210 tomcat.lucky.com

浏览器访问 tomcat.lucky.com,出现如下页面:

img

10.3 通过 Ingress-nginx-Controller 实现按流量百分比代理

场景: 切一定比例的流量给新版本

​ 假设线上运行了一套对外提供 7 层服务的 Service B 服务,后来修复了一些问题,需要灰度上线一个新版本 Service B’,但又不想直接替换掉原来的 Service B,而是让先切 10% 的流量到新版本,等观察一段时间稳定后再逐渐加大新版本的流量比例直至完全替换旧版本,最后再滑下线旧版本,从而实现切一定比例的流量给新版本:

img

1、部署两个版本的服务

以简单的 nginx 为例,先部署一个 v1 版本:

## 工作节点导入镜像
$ docker load -i openresty.tar.gz 

$ vim v1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v1
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - name: nginx
        image: "openresty/openresty:centos"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          protocol: TCP
          containerPort: 80
        volumeMounts:
        - mountPath: /usr/local/openresty/nginx/conf/nginx.conf
          name: config
          subPath: nginx.conf
      volumes:
      - name: config
        configMap:
          name: nginx-v1
---
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: nginx
    version: v1
  name: nginx-v1
data:
  nginx.conf: |-
    worker_processes  1;
    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }
    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("nginx-v1")
                ';
            }
        }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-v1
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: nginx
    version: v1

创建资源对象

$ kubectl apply -f v1.yaml

再部署一个 v2 版本:

$ vim v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v2
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image: "openresty/openresty:centos"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          protocol: TCP
          containerPort: 80
        volumeMounts:
        - mountPath: /usr/local/openresty/nginx/conf/nginx.conf
          name: config
          subPath: nginx.conf
      volumes:
      - name: config
        configMap:
          name: nginx-v2
---
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: nginx
    version: v2
  name: nginx-v2
data:
  nginx.conf: |-
    worker_processes  1;
    events {
        accept_mutex on;
        multi_accept on;
        use epoll;
        worker_connections  1024;
    }
    http {
        ignore_invalid_headers off;
        server {
            listen 80;
            location / {
                access_by_lua '
                    local header_str = ngx.say("nginx-v2")
                ';
            }
        }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-v2
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: nginx
    version: v2

创建资源对象

[root@xuegod63 v1-v2]# kubectl apply -f v2.yaml

2、再创建一个 Ingress,对外暴露服务,指向 v1 版本的服务:

$ vim v1-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v1
           port:
            number: 80
$ kubectl apply -f v1-ingress.yaml

访问验证一下:

$ curl -H "Host: canary.example.com" http://EXTERNAL-IP/

EXTERNAL-IP 是 ingress-nginx-controller 这个是 pod 的 ip 地址

$ curl -H "Host: canary.example.com" http://192.168.2.204

返回结果如下:

nginx-v1

3、测试按照流量百分比代理 pod:

$ vim v1-weight.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
  name: nginx-canary
spec:
  rules:
  - host: canary.example.com
    http:
      paths:
      - path: /  #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"
        pathType:  Prefix
        backend:  #配置后端服务
         service:
           name: nginx-v2
           port:
            number: 80
$ kubectl apply -f v1-weight.yaml

测试访问:

$ for i in {1..10}; do curl -H "Host: canary.example.com" http://EXTERNAL-IP; done; 

$ for i in {1..10}; do curl -H "Host: canary.example.com" http://192.168.2.204; done;

返回如下结果:

nginx-v1
nginx-v2
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1
nginx-v1

可以看到,大概只有十分之一的几率由 v2 版本的服务响应,符合 10% 服务权重的设置

10.4 Configmap 基本介绍

​ ConfigMap 是 Kubernetes 中的一种资源对象,用于存储应用程序的配置数据。它可以用于将配置信息与应用程序的 Pod 解耦,从而实现配置的动态管理和灵活性

​ 以下是 ConfigMap 的一些基本介绍和特点

1、存储配置数据:ConfigMap 可以存储各种类型的配置数据,例如环境变量、命令行参数、配置文件等。它将配置数据以键值对的形式组织,并提供一个唯一的名称供应用程序使用。

2、解耦配置与应用程序:ConfigMap 允许将应用程序的配置从应用程序本身中分离出来,以实现配置和应用程序的解耦。这样,配置可以在不重启应用程序的情况下进行修改和更新,提供了更好的灵活性和可维护性。

3、应用程序访问配置:应用程序可以通过环境变量、命令行参数或在容器内挂载配置文件的方式来访问 ConfigMap 中的配置数据。这使得应用程序可以在运行时动态地获取和使用配置信息。

4、容易管理和更新:ConfigMap 的配置数据可以通过命令行工具(如 kubectl)或使用Kubernetes 的 API 进行创建、更新和删除。这使得管理和更新配置变得简单和可扩展,可以与应用程序的部署和扩展自动化流程结合使用。

5、与 Pod 的关联:ConfigMap 可以与 Pod 进行关联,以便将配置数据传递给 Pod 中的容器。您可以通过将 ConfigMap 挂载为容器的卷(Volume)或设置容器的环境变量来实现配置的传递。

​ 总而言之,ConfigMap 是 Kubernetes 中的一种资源对象,用于存储应用程序的配置数据。它通过解耦配置和应用程序,提供了配置的动态管理和灵活性。使用 ConfigMap,您可以轻松地管理和更新应用程序的配置,同时使配置与应用程序的部署和扩展过程解耦。

10.5 Configmap 创建方法

10.5.1 命令行直接创建

直接在命令行中指定 configmap 参数创建,通过--from-literal 指定参数

$ kubectl create configmap tomcat --from-literal=tomcat_port=8080 --from-literal=server_name=myapp.tomcat.com

[root@k8s-master01 configmap]# kubectl describe configmap tomcat
Name:         tomcat
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
server_name:
----
myapp.tomcat.com
tomcat_port:
----
8080

BinaryData
====

Events:  <none>

10.5.2 通过文件创建

通过指定文件创建一个 configmap,--from-file=<文件>

[root@k8s-master01 configmap]# vim nginx.conf

server {
server_name www.nginx.com; listen 80;
}

定义一个 key 是www,值是 nginx.conf 中的内容

$ kubectl create configmap nginx --from-file=www=./nginx.conf

[root@k8s-master01 configmap]# kubectl describe configmap nginx
Name:         nginx
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
www:
----
server {
server_name www.nginx.com; listen 80;
}


BinaryData
====

Events:  <none>

10.5.3 编写 configmap 资源清单 YAML 文件

$ vim mysql-configmap.yaml 

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  log: "1"
  lower: "2"
$ kubectl apply -f mysql-configmap.yaml 

10.6 使用 Configmap

10.6.1 通过环境变量引入:使用 configMapKeyRef

1、创建configmap

创建一个存储 mysql 配置的configmap

$ vim mysql.yaml 

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
  labels:
    app: mysql
data:
  log: "1"
  lower: "1"
$ kubectl apply -f mysql.yaml
2、创建pod,对接configmap

创建 pod,引用 Configmap 中的内容

$ vim mysql-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
spec:
  containers:
  - name: mysql
    image: busybox
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    env:
    - name: log_bin   #定义环境变量log_bin
      valueFrom: 
        configMapKeyRef:
          name: mysql     #指定configmap的名字
          key: log #指定configmap中的key
    - name: lower   #定义环境变量lower
      valueFrom:
        configMapKeyRef:
          name: mysql
          key: lower
  restartPolicy: Never

更新资源清单文件

$ kubectl apply -f mysql-pod.yaml 
3、测试
$ kubectl exec -it mysql-pod -- /bin/sh

/ ## printenv |egrep "log_bin|lower"
log_bin=1
lower=2

10.6.2 通过环境变量引入:使用 envfrom

$ vim mysql-pod-envfrom.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod-envfrom
spec:
  containers:
  - name: mysql
    image: busybox
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    envFrom: 
    - configMapRef:
       name: mysql     #指定configmap的名字
  restartPolicy: Never

更新资源清单文件

$ kubectl apply -f mysql-pod-envfrom.yaml 

验证

$ kubectl exec -it mysql-pod-envfrom -- /bin/sh

## printenv|egrep "lower|log"
lower=2
log=1

10.6.3 把 configmap 做成 volume,挂载到 pod

1、创建volume类型的configmap
$ vim mysql-1.yaml 

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-1
data:
    log: "1"
    lower: "1"
    my.cnf: |
      [mysqld]
      Welcome=xuegod

更新资源清单文件

$ kubectl apply -f mysql-1.yaml 
2、创建pod对接configmap
$ vim mysql-pod-volume.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod-volume
spec:
  containers:
  - name: mysql
    image: busybox
    command: [ "/bin/sh","-c","sleep 3600" ]
    volumeMounts:
    - name: mysql-config
      mountPath: /tmp/config
  volumes:
  - name: mysql-config
    configMap:
      name: mysql-1
  restartPolicy: Never

更新资源清单文件

$ kubectl apply -f mysql-pod-volume.yaml
3、验证
$ kubectl get pod |grep mysql-pod-volume
mysql-pod-volume    1/1     Running   0          18s

$  kubectl exec -it mysql-pod-volume -- /bin/sh

## cd /tmp/config/
/tmp/config ## ls
log     lower   my.cnf
## cat my.cnf
[mysqld]
Welcome=qingcai
## cat log
1
## cat lower 
1

10.7 Configmap 热更新

$ kubectl edit configmap mysql-config

把 log:“1”变成 log: “2”

img

保存退出

$ kubectl exec -it mysql-pod-volume -- /bin/sh

## cat /tmp/config/log 
2

发现 log 值变成了 2,更新生效了

注意:

更新 ConfigMap 后

使用该 ConfigMap 挂载的 Env 不会同步更新

使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间才能同步更新

​ ENV 是在容器启动的时候注入的,启动之后 kubernetes 就不会再改变环境变量的值,且同一个namespace 中的 pod 的环境变量是不断累加的,为了更新容器中使用 ConfigMap 挂载的配置,可以通过滚动更新 pod 的方式来强制重新挂载 ConfigMap,也可以在更新了 ConfigMap 后,先将副本数设置为 0,再扩容 pod

10.8 Secret 概述

10.8.1 Secret 是什么?

​ Kubernetes (k8s) Secrets 是 Kubernetes 集群中的一种资源对象,用于存储和管理敏感信息,例如密码、令牌、API 密钥和证书等。

​ Kubernetes Secrets 的主要目的是将敏感数据与应用程序代码分离,并提供一种安全的方式来存储和传递这些敏感数据给容器化的应用程序。它们以加密的形式保存,并且只能在需要时才能被解密和使用。

以下是关于 Kubernetes Secrets 的一些基本特点和用法:

1、类型:Kubernetes Secrets 可以存储任意字节的数据,但通常用于存储字符串格式的敏感信息。

2、创建和管理:可以使用 Kubernetes 命令行工具(kubectl)或 Kubernetes API 来创建和管理Secrets。

3、加密和解密:Kubernetes Secrets 会将存储的敏感数据加密,并使用 Base64 编码进行存储。在使用 Secrets时,Kubernetes 会自动将其解码并将解密的值提供给应用程序。

4、Secret类型:Kubernetes 提供了几种不同的 Secret 类型,包括:

1)Opaque:适用于存储任意类型的敏感数据,默认情况下以 Base64 编码进行存储。

2)Service Account:用于将 Pod 与 Service Account 关联,并将 Service Account 的 Token注入到 Pod 中,以便 Pod 可以与 Kubernetes API 进行交互。

3) Docker Registry:用于存储与私有 Docker 注册表的认证信息,以便 Kubernetes 可以拉取私有镜像。

4) TLS:用于存储 TLS 证书和私钥。

5、使用 Secrets:在 Kubernetes 中使用 Secrets 时,可以通过环境变量、挂载文件或通过卷的方式将其传递给 Pod 中的应用程序。

1) 环境变量:可以将 Secret 的值作为环境变量传递给应用程序。

2) 挂载文件:可以将 Secret 中的值以文件的形式挂载到 Pod 中,应用程序可以读取这些文件。

3) 通过卷:可以将 Secret 中的值作为卷挂载到 Pod 中,应用程序可以从该卷中读取敏感数据。**

​ Kubernetes Secrets 提供了一种安全和可扩展的方式来管理敏感数据,并帮助将敏感信息与应用程序代码分离,从而更好地保护应用程序和集群的安全性。

10.8.2 使用 Secret

1、通过环境变量引入 Secret

把 mysql 的root 用户的 password 创建成 secret

$ kubectl create secret generic mysql-password --from-literal=password=pod**666

$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-tqdp5   kubernetes.io/service-account-token   3      26d
mysql-password        Opaque                                1      19s
[root@k8s-master01 secret]# kubectl describe secret mysql-password 
Name:         mysql-password
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  8 bytes

password 的值是加密的,

但 secret 的加密是一种伪加密,它仅仅是将数据做了 base64 的编码.

创建 pod,引用 secret

$ vim pod-secret.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    env:
     - name: MYSQL_ROOT_PASSWORD   #它是Pod启动成功后,Pod中容器的环境变量名.
       valueFrom:
          secretKeyRef:
            name: mysql-password  #这是secret的对象名
            key: password      #它是secret中的key名
$ kubectl apply -f pod-secret.yaml 

$ kubectl get pod 
NAME         READY   STATUS    RESTARTS   AGE
pod-secret   1/1     Running   0          14s

$  kubectl exec -it pod-secret -- /bin/sh
## printenv |grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=pod**666

2、通过 volume 挂载 Secret

1)创建 Secret

手动加密,基于 base64 加密

$ echo -n 'admin' | base64
YWRtaW4=

$ echo -n 'qingcai' | base64
cWluZ2NhaQ==

解码:

$ echo cWluZ2NhaQ== | base64 -d
qingcai
2)创建 yaml 文件
$ vim secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: cWluZ2NhaQ==
$ kubectl apply -f secret.yaml 

$ kubectl get secret mysecret
NAME       TYPE     DATA   AGE
mysecret   Opaque   2      27s
3)将 Secret 挂载到 Volume 中
$ vim pod_secret_volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-volume
spec:
  containers:
  - name: myapp
    image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: mysecret
$ kubectl apply -f pod_secret_volume.yaml

$ kubectl get pod pod-secret-volume
NAME                READY   STATUS    RESTARTS   AGE
pod-secret-volume   1/1     Running   0          22s


$ kubectl exec -it pod-secret-volume -- /bin/sh

/ ## ls /etc/secret
password  username

/ ## cat /etc/secret/username
admin

/ ## cat /etc/secret/password
qingcai

由上可见,在 pod 中的 secret 信息实际已经被解密。