写在开篇

持续接上篇,《一文理解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 mainimport (        "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:latestWORKDIR /appCOPY static /app/staticCOPY main /appENV 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:20230515v22023/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: v1kind: Podmetadata:  name: gowebspec:  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 podNAME    READY   STATUS    RESTARTS   AGEgoweb   1/1     Running   0          29s[root@k8s-b-master ~]# kubectl exec -it goweb -- sh/app # psPID   USER     TIME  COMMAND    1 root      0:00 ./main -p 9091   11 root      0:00 sh   17 root      0:00 ps/app # 
  1. 残缺的yaml

<!---->

apiVersion: v1metadata:  name: gowebdata:  port: "9091"kind: ConfigMap---apiVersion: apps/v1kind: Deploymentmetadata:  labels:    app: goweb  name: gowebspec:  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