跳转至

14. pod优化2-敏感信息隐藏

1. 为什么要统一管理环境变量

# 为什么要统一管理环境变量

- 环境变量中有很多敏感的信息,比如账号密码,直接暴漏在yaml文件中存在安全性问题
- 团队内部一般存在多个项目,这些项目直接存在配置相同环境变量的情况,因此可以统一维护管理
- 对于开发、测试、生产环境,由于配置均不同,每套环境部署的时候都要修改yaml,带来额外的开销

# k8s提供两类资源,configMap和Secret,可以用来实现业务配置的统一管理, 允许将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性 。

2. configmap

1. 创建configmap.yaml

# configMap,通常用来管理应用的配置文件或者环境变量
cd /k8s/pod/myblog/two-pod/
vim configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myblog
  namespace: demo
data:
  MYSQL_HOST: "81.70.4.171"
  MYSQL_PORT: "3306"

2. 创建configmap

kubectl apply -f configmap.yaml
root@k8s-master:~# cd /k8s/pod/myblog/two-pod/
root@k8s-master:/k8s/pod/myblog/two-pod# vim configmap.yaml
root@k8s-master:/k8s/pod/myblog/two-pod#
root@k8s-master:/k8s/pod/myblog/two-pod# kubectl apply -f configmap.yaml
configmap/myblog created
root@k8s-master:/k8s/pod/myblog/two-pod# kubectl -n demo get cm
NAME               DATA   AGE
kube-root-ca.crt   1      169m
myblog             2      8s
root@k8s-master:/k8s/pod/myblog/two-pod#

3. secret

1. secret介绍

# Secret,管理敏感类的信息,默认会base64编码存储,有三种类型
    - `Service Account` :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;创建ServiceAccount后,Pod中指定serviceAccount后,自动创建该ServiceAccount对应的secret;

    - `Opaque` : base64编码格式的Secret,用来存储密码、密钥等;

    - `kubernetes.io/dockerconfigjson` :用来存储私有docker registry的认证信息。

2. 创建secret.yaml

vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: myblog
  namespace: demo
type: Opaque
data:
  MYSQL_USER: cm9vdA==      #注意加-n参数, echo -n root|base64
  MYSQL_PASSWD: MTIzNDU2

3. 创建secret方式1(不推荐)

kubectl create -f secret.yaml
kubectl -n demo get secret

4. 创建secret方式2(推荐)

如果不习惯这种方式,可以通过如下方式:

## 1. 创建用户及密码txt文件
vim secret.txt

MYSQL_USER=root
MYSQL_PASSWD=123456

## 2. 创建secret
kubectl -n demo create secret generic myblog --from-env-file=secret.txt 
root@k8s-master:/k8s/pod/myblog/two-pod# vim secret.txt
root@k8s-master:/k8s/pod/myblog/two-pod#
root@k8s-master:/k8s/pod/myblog/two-pod# kubectl -n demo create secret generic myblog --from-env-file=secret.txt
secret/myblog created
root@k8s-master:/k8s/pod/myblog/two-pod#
root@k8s-master:/k8s/pod/myblog/two-pod# kubectl -n demo get secret
NAME                  TYPE                                  DATA   AGE
default-token-wmvdt   kubernetes.io/service-account-token   3      170m
myblog                Opaque                                2      10s
root@k8s-master:/k8s/pod/myblog/two-pod#

4. 修改mysql

1. 原来的mysql.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  namespace: demo
  labels:
    component: mysql
spec:
  hostNetwork: true     # 声明pod的网络模式为host模式,效果通docker run --net=host
  volumes: 
  - name: mysql-data
    hostPath: 
      path: /opt/mysql/data
  nodeSelector:         # 使用节点选择器将Pod调度到指定label的节点
    component: mysql
  containers:
  - name: mysql
    image: mysql:5.7-utf8
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123456"
    - name: MYSQL_DATABASE
      value: "myblog"
    resources:          #资源限制
      requests:
        memory: 100Mi
        cpu: 50m
      limits:
        memory: 500Mi
        cpu: 100m
    readinessProbe:     #探针
      tcpSocket:
        port: 3306
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 3306
      initialDelaySeconds: 15
      periodSeconds: 20
    volumeMounts:
    - name: mysql-data
      mountPath: /var/lib/mysql

2. 修改为其中secret相关的内容

vim mysql-with-config.yaml
...
spec:
  containers:
  - name: mysql
    image: mysql:5.7-utf8
    env:
    - name: MYSQL_USER      #这里后面变成来自secret了
      valueFrom:        
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    #这里后面变成来自secret了
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD
    - name: MYSQL_DATABASE
      value: "myblog"
...

3. 之前的env和现在的env对比

#之前的env
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123456"
    - name: MYSQL_DATABASE
      value: "myblog"
#现在的env
    env:
    - name: MYSQL_USER  
      valueFrom:        
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD

#虽然变多变复杂了,但是更安全了!

4. 修改后的yaml

vim mysql-with-config.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  namespace: demo
  labels:
    component: mysql
spec:
  hostNetwork: true     # 声明pod的网络模式为host模式,效果通docker run --net=host
  volumes: 
  - name: mysql-data
    hostPath: 
      path: /opt/mysql/data
  nodeSelector:         # 使用节点选择器将Pod调度到指定label的节点
    component: mysql
  containers:
  - name: mysql
    image: mysql:5.7-utf8
    ports:
    - containerPort: 3306
    env:
    - name: MYSQL_USER      #这里后面变成来自secret了
      valueFrom:        
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    #这里后面变成来自secret了
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD
    - name: MYSQL_DATABASE
      value: "myblog"
    resources:          #资源限制
      requests:
        memory: 100Mi
        cpu: 50m
      limits:
        memory: 500Mi
        cpu: 100m
    readinessProbe:     #探针
      tcpSocket:
        port: 3306
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 3306
      initialDelaySeconds: 15
      periodSeconds: 20
    volumeMounts:
    - name: mysql-data
      mountPath: /var/lib/mysql

5. 修改myblog

1. 原来的myblog.yaml

apiVersion: v1
kind: Pod
metadata:
  name: myblog
  namespace: demo
  labels:
    component: myblog
spec:
  containers:
  - name: myblog
    image: myblog:v1
    imagePullPolicy: IfNotPresent
    env:
    - name: MYSQL_HOST   
      value: "81.70.4.171"      # 这里不知道写宿主机IP是否可以???可以,因为mysql使用的网络模式是host模式
    - name: MYSQL_PASSWD
      value: "123456"
    ports:
    - containerPort: 8002
    resources:
      requests:
        memory: 100Mi
        cpu: 50m
      limits:
        memory: 500Mi
        cpu: 100m
    livenessProbe:
      httpGet:
        path: /blog/index/
        port: 8002
        scheme: HTTP
      initialDelaySeconds: 10  # 容器启动后第一次执行探测是需要等待多少秒
      periodSeconds: 15     # 执行探测的频率
      timeoutSeconds: 2     # 探测超时时间
    readinessProbe: 
      httpGet: 
        path: /blog/index/
        port: 8002
        scheme: HTTP
      initialDelaySeconds: 10 
      timeoutSeconds: 2
      periodSeconds: 15

2. 修改其中configmap和secret相关的内容

vim myblog-with-config.yaml
spec:
  containers:
  - name: myblog
    image: myblog:v1
    imagePullPolicy: IfNotPresent
    env:
    - name: MYSQL_HOST  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_HOST
    - name: MYSQL_PORT  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_PORT
    - name: MYSQL_USER  #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD

3. 之前的env和现在的env对比

#之前的env和port
    env:
    - name: MYSQL_HOST   
      value: "81.70.4.171"      # 这里不知道写宿主机IP是否可以???可以,因为mysql使用的网络模式是host模式
    - name: MYSQL_PASSWD
      value: "123456"
    ports:
    - containerPort: 8002
#现在的env和port
    env:
    - name: MYSQL_HOST  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_HOST
    - name: MYSQL_PORT  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_PORT
    - name: MYSQL_USER  #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD

4. 修改后的yaml

vim myblog-with-config.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myblog
  namespace: demo
  labels:
    component: myblog
spec:
  containers:
  - name: myblog
    image: myblog:v1
    imagePullPolicy: IfNotPresent
    env:
    - name: MYSQL_HOST  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_HOST
    - name: MYSQL_PORT  #修改为使用configmap
      valueFrom:
        configMapKeyRef:
          name: myblog
          key: MYSQL_PORT
    - name: MYSQL_USER  #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_USER
    - name: MYSQL_PASSWD    #修改为使用secret
      valueFrom:
        secretKeyRef:
          name: myblog
          key: MYSQL_PASSWD
    resources:
      requests:
        memory: 100Mi
        cpu: 50m
      limits:
        memory: 500Mi
        cpu: 100m
    livenessProbe:
      httpGet:
        path: /blog/index/
        port: 8002
        scheme: HTTP
      initialDelaySeconds: 10  # 容器启动后第一次执行探测是需要等待多少秒
      periodSeconds: 15     # 执行探测的频率
      timeoutSeconds: 2     # 探测超时时间
    readinessProbe: 
      httpGet: 
        path: /blog/index/
        port: 8002
        scheme: HTTP
      initialDelaySeconds: 10 
      timeoutSeconds: 2
      periodSeconds: 15

6. 重新创建测试

1. 删除原来的pod

kubectl -n demo get pod
kubectl -n demo delete pod myblog
kubectl -n demo delete pod mysql

2. 新建pod

kubectl apply -f myblog-with-config.yaml
kubectl apply -f mysql-with-config.yaml

3. 查看pod的IP

kubectl -n demo get pod -owide
root@k8s-master:/k8s/pod/myblog/two-pod# kubectl -n demo get pod -owide
NAME     READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
myblog   1/1     Running   0          24s   10.244.0.37   k8s-master   <none>           <none>
mysql    1/1     Running   0          23s   81.70.4.171   k8s-master   <none>           <none>

3. curl测试

curl 10.244.0.37:8002/blog/index/
root@k8s-master:/k8s/pod/myblog/two-pod# curl 10.244.0.37:8002/blog/index/
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h3>我的博客列表:</h3>


    </br>
    </br>
    <a href=" /blog/article/edit/0 ">写博客</a>

</body>
</html>

7. 总结

# 在部署不同的环境时,pod的yaml无须再变化,只需要在每套环境中维护一套ConfigMap和Secret即可。
# 但是注意configmap和secret不能跨namespace使用,且更新后,pod内的env不会自动更新,重建后方可更新。

最后更新: 2022-02-22 04:55:01