乐趣区

关于kubernetes:下篇1将-ConfigMap-中的键值对作为容器的环境变量

写在开篇

持续接上篇,《一文理解 K8S 的 ConfigMap》。上篇聊过,官网文档中提到的能够应用上面 4 种形式来应用 ConfigMap 配置 Pod 中的容器:

  • 容器的环境变量:能够将 ConfigMap 中的键值对作为容器的环境变量。
  • 在只读卷外面增加一个文件,让利用来读取:能够将 ConfigMap 中的内容作为一个只读卷挂载到 Pod 中的容器外部,而后在容器内读取挂载的文件。
  • 编写代码在 Pod 中运行,应用 Kubernetes API 来读取 ConfigMap:能够在 Pod 中运行自定义代码,应用 Kubernetes API 来读取 ConfigMap 中的内容。
  • 在容器命令和参数内:能够在容器的启动命令中通过援用环境变量的形式来应用 ConfigMap。

为了管制篇幅,打算分 4 篇进行分享,本篇分享以应用“容器的环境变量”的形式进行实战。对于应用 ConfigMap 的更多详情,可参考官网文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/confi…

开发示例利用

  1. goweb 我的项目目录构造

<!—->

[root@workhost goweb]# tree
.
├── Dockerfile
├── go.mod
├── main.go
├── README.md
└── static
    └── login.html
  1. main.go

<!—->

package main

import (
        "fmt"
        "log"
        "net/http"
        "os"
        "text/template"
)

type Message struct {Msg string}

func home(w http.ResponseWriter, r *http.Request) {
        if r.Method == "GET" {w.Header().Set("Location", "/login")
                w.WriteHeader(http.StatusFound)
        }
}

func login(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("./static/login.html")
        if r.Method == "GET" {t.Execute(w, nil)
        }
}

func main() {http.HandleFunc("/", home)
        http.HandleFunc("/login", login)
        args := os.Args
        if args[1] == "-p" {port := args[2]
                listenAddr := fmt.Sprintf(":%v", port)
                log.Println("ListenAndserve", listenAddr)
                err := http.ListenAndServe(listenAddr, nil)
                if err != nil {log.Println(err)
                }
        }
}

本次代码在上次的根底上做了点小革新:接受命令行参数,应用 os.Args 获取程序运行时的参数。如果传入的参数中蕴含 -p,则阐明须要指定监听的端口,将端口值读取进去并应用 http.ListenAndServe 启动 HTTP 服务。

  1. login.html

<!—->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Login K8S</title>
    <style>
      body {
        background-color: #f2f2f2;
        font-family: Arial, sans-serif;
      }

      #login-box {
        background-color: #fff;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        margin: 100px auto;
        max-width: 400px;
        padding: 20px;
      }

      h1 {
        font-size: 24px;
        margin: 0 0 20px;
        text-align: center;
      }

      label {
        display: block;
        font-size: 14px;
        font-weight: bold;
        margin-bottom: 5px;
      }

      input[type="text"],
      input[type="password"] {
        border-radius: 3px;
        border: 1px solid #ccc;
        box-sizing: border-box;
        font-size: 14px;
        padding: 10px;
        width: 100%;
      }

      input[type="submit"] {
        background-color: #007bff;
        border: none;
        border-radius: 3px;
        color: #fff;
        cursor: pointer;
        font-size: 14px;
        padding: 10px;
        width: 100%;
      }

      input[type="submit"]:hover {background-color: #0069d9;}

      .error-message {
        color: #dc3545;
        font-size: 14px;
        margin: 10px 0;
        text-align: center;
      }
    </style>
  </head>
  <body>
    <div id="login-box">
      <h1> 容器云治理平台 </h1>
      <form>
        <label for="username"> 账号:</label>
        <input type="text" id="username" name="username">

        <label for="password"> 明码:</label>
        <input type="password" id="password" name="password">

        <input type="submit" value="登录">
      </form>
      <div class="error-message"></div>
    </div>

    <script>
      const form = document.querySelector('form');
      const errorMessage = document.querySelector('.error-message');

      form.addEventListener('submit', function(event) {event.preventDefault();

        const username = document.getElementById('username').value;
        const password = document.getElementById('password').value;

        if (username === ''|| password ==='') {errorMessage.textContent = 'Please enter a username and password.';} else if (username !== 'admin' || password !== 'password') {errorMessage.textContent = 'Incorrect username or password.';} else {alert('Login successful!');
        }
      });
    </script>
  </body>
</html>

实战:以应用“容器的环境变量”的形式

  1. 制作镜像

编写 Dockerfile:

FROM alpine:latest
WORKDIR /app
COPY static /app/static
COPY main /app
ENV PORT 80 # 设置默认端口号为 80,这个值将在容器启动时被笼罩
CMD ["/bin/sh", "-c", "./main -p $PORT"]

构建镜像和推送到公有 harbor:

docker build -t 192.168.11.254:8081/webdemo/goweb:20230515v2 .
docker push 192.168.11.254:8081/webdemo/goweb:20230515v2
  1. 测试

<!—->

[root@workhost goweb]# docker run --rm -it -p 80:9090 -e PORT=9090 192.168.11.254:8081/webdemo/goweb:20230515v2
2023/05/15 02:08:43 ListenAndserve :9090

应用 -p 参数将本地主机的 80 端口映射到容器外部的 9090 端口,应用 -e 参数设置环境变量 PORT 的值为 9090,能够失常启动,阐明在启动时曾经笼罩掉了默认端口 80,且能失常拜访:

  1. 创立 configmap

<!—->

kubectl create configmap goweb --from-literal=port=9091

执行命令后将会创立一个名为 goweb 的 ConfigMap,其中蕴含一个名为 port 的键,值为 9091。这样,在 Pod 中应用 &dollar;PORT 环境变量时,就能够将其设置为 9091。

阐明:–from-literal=port=9091 示意要将 port 这个键的值设置为 9091,这里应用 –from-literal 标记示意将文本作为字面量值创立 ConfigMap。

  1. 创立 pod

<!—->

apiVersion: v1
kind: Pod
metadata:
  name: goweb
spec:
  containers:
  - name: goweb
    image: 192.168.11.254:8081/webdemo/goweb:20230515v2
    env:
    - name: PORT
      valueFrom:
        configMapKeyRef:
          name: goweb
          key: port

下面 yaml 中,通过设置 env 字段,将 ConfigMap 中的 port 键值对作为环境变量注入到容器中的应用程序中。应用了 valueFrom 字段指定了 ConfigMap 的名称和键,从而将 ConfigMap 中的 port 值注入到容器的 PORT 环境变量中。这样,在容器启动后,应用程序就能够通过读取 PORT 环境变量的值来获取应该监听的端口,实现了将 ConfigMap 的值注入到容器的环境变量中的性能。

  1. 进入 pod 验证

<!—->

[root@k8s-b-master ~]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
goweb   1/1     Running   0          29s
[root@k8s-b-master ~]# kubectl exec -it goweb -- sh
/app # ps
PID   USER     TIME  COMMAND
    1 root      0:00 ./main -p 9091
   11 root      0:00 sh
   17 root      0:00 ps
/app # 
  1. 残缺的 yaml

<!—->

apiVersion: v1
metadata:
  name: goweb
data:
  port: "9091"
kind: ConfigMap
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: goweb
  name: goweb
spec:
  replicas: 3
  selector:
    matchLabels:
      app: goweb
  template:
    metadata:
      labels:
        app: goweb
    spec:
      containers:
        - name: goweb
          image: 192.168.11.254:8081/webdemo/goweb:20230515v2
          env:
          - name: PORT
            valueFrom:
              configMapKeyRef:
                name: goweb
                key: port

本文转载于 WX 公众号:不背锅运维(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/14zOTnmUSK39PHj8t9m3mQ

退出移动版