写在开篇
持续接上篇,《一文理解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...
开发示例利用
- goweb我的项目目录构造
<!---->
[root@workhost goweb]# tree.├── Dockerfile├── go.mod├── main.go├── README.md└── static └── login.html
- 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 服务。
- 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>
实战:以应用“容器的环境变量”的形式
- 制作镜像
编写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
- 测试
<!---->
[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,且能失常拜访:
- 创立configmap
<!---->
kubectl create configmap goweb --from-literal=port=9091
执行命令后将会创立一个名为 goweb 的 ConfigMap,其中蕴含一个名为 port 的键,值为 9091。这样,在 Pod 中应用 $PORT 环境变量时,就能够将其设置为 9091。
阐明:--from-literal=port=9091 示意要将 port 这个键的值设置为 9091,这里应用 --from-literal 标记示意将文本作为字面量值创立 ConfigMap。
- 创立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 的值注入到容器的环境变量中的性能。
- 进入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 #
- 残缺的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