K8S容器编排之ConfigMap 用于动态应用程序的实践

栏目: 编程工具 · 发布时间: 6年前

内容简介:导言:在 Kubernetes 中,ConfigMap 是允许管理员将配置组件与镜像内容解耦,使容器化应用程序产生可移植性的一种资源。ConfigMap 可以与 Kubernetes Pod 一起使用,用于动态添加或更改容器中的使用文件。本文将阐述 Kubernetes ConfigMap 如何利用动态应用程序的方法来解决轻量级文件服务器部署到 Kubernetes 集群中的问题。生产环境中很多应用程序的配置可能需要通过配置文件、命令行参数和环境变量的组合来完成。这些配置应该从镜像中解耦,通过这种方式来保持

导言:在 Kubernetes 中,ConfigMap 是允许管理员将配置组件与镜像内容解耦,使容器化应用程序产生可移植性的一种资源。ConfigMap 可以与 Kubernetes Pod 一起使用,用于动态添加或更改容器中的使用文件。本文将阐述 Kubernetes ConfigMap 如何利用动态应用程序的方法来解决轻量级文件服务器部署到 Kubernetes 集群中的问题。

ConfigMap 概览

生产环境中很多应用程序的配置可能需要通过配置文件、命令行参数和环境变量的组合来完成。这些配置应该从镜像中解耦,通过这种方式来保持容器化应用程序的可移植性。在 Kubernetes 1.2 版本以后,研发人员引入 ConfigMap 来处理这种类型的配置数据。

简单来说,ConfigMap 是容器的配置管理。在容器运行时,ConfigMap 把配置文件、命令行参数、环境变量、端口号和其他配置组件绑定到 Pod 的容器和系统组件上,同时将应用的代码和配置区分开。从数据角度来看,ConfigMap 的类型只是键值对。从应用角度来看,管理员可以从不同角度来配置它。

在 Pod 中使用 ConfigMap 大致有以下三种方式:

  • 将 ConfigMap 中的数据设置为环境变量;
  • 将 ConfigMap 中的数据设置为命令行参数;
  • 将 ConfigMap 作为文件或目录挂载。
    另外,由于应用会从环境变量和包含配置数据的文件中读取配置信息,所以 ConfigMap 是可以支持这两种读取方式的。

创配置 ConfigMap 的注意事项

众所周知, ConfigMapSecret 很相似。但是, ConfigMap 主要用来存储和共享非敏感、未加密的配置信息。 Secret 是用来存储敏感信息(例如:密码)。除了这个大家都了解的注意事项外,在配置 ConfigMap 时还要注意以下 4 点:

  • ConfigMap 必须在被 Pod 使用之前创建;
  • Pod 只能使用在同一 Namespace 中的 ConfigMap;
  • ConfigMap 大小的配额是一个已经设置好的功能;
  • Kubelet 只支持 API 服务器中的 Pod 使用 ConfigMap。
    注:API 服务器中的 Pod 包括用 Kubectl 创建的 Pod、间接通过 replication controller 创建的 Pod,不包括通过 Kubelet 的 –manifest-url 标志创建的 Pod,也不包括从它的 REST API 创建的 Pod。

ConfigMap 用于动态应用程序的实践

需要解决的问题

作为 Kubernetes 安装程序的一部分,很多人希望可以将轻量级文件服务器部署到 Kubernetes 集群中以此处理默认(root - path)入口请求。并且,我认为如果我们可以编辑 index.html 和 CSS 文件而不必重新部署应用程序。

为了解决这个用例,我们决定构建一个 Golang 应用程序,将其部分文件系统映射到 Kubernetes ConfigMap 资源中。

Golang Fileserver

文件服务器应用程序的设计非常简单,它仅用于提供静态内容。这种方式可以帮助 Kubernetes 用户使用入口功能。

package main
import (
“log”
“net/http”
)
func main() {
fs := http.FileServer(http.Dir(“html”))
http.Handle(“/”, fs)
log.Println(“Listening…”)
http.ListenAndServe(“:8080”, nil)
}

应用程序使用以下 Dockerfile 内容构建容器镜像。它是一个两阶段的 Dockerfile,首先在 Alpine 容器中执行 Golang 构建,然后将已编译的二进制和空 helm 目录复制到最终的 scratch-based 镜像上。

# build stage  
FROM golang:alpine AS builder  
WORKDIR /usr/local/go/src  
COPY  main.go .  
RUN CGO_ENABLED=0 GOOS=linux go build -o main .  


# final stage  
FROM scratch  
WORKDIR /  
COPY --from=builder /usr/local/go/src/main main  
COPY html html  
EXPOSE 8080  
ENTRYPOINT ["/main"]

在 Golang 应用程序中使用 scratch 容器来部署 Golang 容器是一种更安全、更轻量级的方法。

部署和运行

我使用 make 来自动化 Docker 操作。以下是此应用程序的 Makefile 。

VERSION?= 0.0.1   
NAME?=“ingress-default”   
AUTHOR?=“Jimmy Ray”   
PORT_EXT?= 8080   
PORT_INT?= 8080    
NO_CACHE?= true   


.PHONY:build run stop clean   


build:   
docker build -f scratch.dockerfile.-t $(NAME)\:$(VERSION) -  no-cache = $(NO_CACHE)


run:   docker   
run --name $(NAME)-d -p $(PORT_EXT):$(PORT_INT)$(NAME) \:$(VERSION)&& docker ps -a --format“{{.ID}} \ t {{.Names}}”| grep $(NAME)   


stop:   
docker rm $$(docker stop $$(docker ps) -a -q --filter“ancestor = $(NAME):$(VERSION)” -  format =“{{.ID}}”))   

clean:   
@rm -f main   

DEFAULT:build

我们可以使用 make 消除重复任务之间的可变性。有了上述的 Makefile,在将测试的应用程序部署到 Kubernetes 之前,我们可以在 Docker 中构建和运行应用程序。

配置 Kubernetes

对于此解决方案,我们需要配置 Kubernetes Namespace、ConfigMap、Deployment、Service 和 Ingress。我们通过使用 kubectl apply -f 的方法来完成此操作(这是对 Kubernetes 集群资源应用更改的声明式方法)。

下面是我们将 munge 的 Kubernetes 资源的 YAML 文件。

apiVersion: v1  
kind: Namespace  
metadata:  
  name: ingress-default 
  labels:  
    app: ingress-default  
---  
kind: ConfigMap  
apiVersion: v1  
metadata:  
  name: ingress-default-static-files  
  namespace: ingress-default   
  labels:  
    app: ingress-default   
data:  
  index.html: |  
    <!doctype html>  
    <html>  
      <head>  
        <meta charset="utf-8">  
        <title>Cluster Ingress Index</title>  
        <link rel="stylesheet" href="main.css">  
      </head>  
      <body>  
        <table class="class1">  
          <tr>  
            <td class="class2">Kubernetes Platform</td>  
          </tr>  
          <tr>  
            <td class="class1">  
              <table class="class3">  
                <tr><td><h1>Cluster Ingress Index</h1></td></tr>  
              </table>  
            </td>  
          </tr>  
          <tr>  
            <td>  
              <table class="class3">  
                <tr>  
                <td>  
                   <h2>The following are links to this cluster's ingress resources:</h2>  
                  </td>  
                </tr>  
                <tr>  
                <td class="class4">  
                    <a href="https://<ROOT_INGRESS_PATH>" target="_blank">Root Ingress</a><br/>  
                    <a href="https://<OTHER_INGRESS_PATH>" target="_blank">Other Ingress</a><br/>   
                 </td>  
               </tr>  
              </table>  
            </td>  
          </tr>  
         </table>  
      </body>  
    </html>  
  main.css: |  
    body {  
      background-color: rgb(224,224,224);  
      font-family: Verdana, Arial, Helvetica, sans-serif;  
      font-size: 100%;  
    }  
    .class1 {  
  ... 
    }  
    .class2 {  
  ... 
    }  
    .class3 {  
  ... 
    }  
    .class4 {  
     ...
    }   
---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  labels:  
    app: ingress-default   
  name: ingress-default  
  namespace: ingress-default 
spec:  
  selector:  
    matchLabels:  
      app: ingress-default  
  replicas: 1  
  template:  
    metadata:  
      labels:  
        app: ingress-default    
      name: ingress-default  
    spec:  
      containers:  
        - name: ingress-default  
          image: <IMAGE_REGISTRY_REPO_TAG>  
          imagePullPolicy: Always  
          resources:  
            limits:  
              cpu: 100m  
              memory: 10Mi  
            requests:  
              cpu: 100m  
              memory: 10Mi  
          volumeMounts:  
            - readOnly: true  
              mountPath: html  
              name: html-files  
      volumes:  
        - name: html-files  
          configMap:  
            name: ingress-default-static-files  
---  
kind: Service  
apiVersion: v1  
metadata:  
  name: ingress-default  
  namespace: ingress-default  
  labels:  
    app: ingress-default  
spec:  
  selector:  
    app: ingress-default  
  ports:  
  - name: http  
    protocol: TCP  
    port: 80  
    targetPort: 8080  
---  
apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
  name: default-ingress  
  namespace: ingress-default  
  annotations:   
    nginx.ingress.kubernetes.io/rewrite-target: /  
    kubernetes.io/ingress.class: "nginx"    
  labels:  
    app: ingress-default  
spec:  
  rules:  
  - http:  
      paths:  
      - path: /  
        backend:  
          serviceName: ingress-default  
          servicePort: 80

正如在 YAML 中的:

ingress-default-static-files

我们可以知道,ConfigMap 包含index.html 和 main.css 文件的内容。通过编辑或替换此 ConfigMap,我们可以更改在 Golang 文件服务器应用程序中的文件。

使用 ConfigMap 作为卷

在 Docker 和 Kubernetes 的中,卷用于解决两个问题:

  • 需要持久化的文件系统;
  • 需要在容器之间共享的文件系统。
    现在,我们将已部署在容器中的卷映射到 ConfigMap 资源中。在下面的代码段中,被配置的 html-files 卷可能被 Pod 中的所有容器使用。

卷会将数据配置映射到 ConfigMap 中的 ingress-default-static-files 上。

...volumes:  
     - name: html-files  
       configMap:  
         name: ingress-default-static-files…

在 Pod 级别配置卷后,我们将配置的卷装入容器中。将此卷的挂载映射到在 Pod 中配置的 html-files 卷上。通过此映射,应用程序容器现在可以访问 ConfigMap 中的两个文件:html/index.html 和 html/mian.css。

...volumeMounts:  
     - readOnly: true  
       mountPath: html  
       name: html-files

当在 Kubernetes 集群中启动 Golang 应用程序时,ingress-default 会在 NGINX 入口控制器中配置上游规则。生成的路径将通过 NGINX 入口控制器将集群边缘连接到ingress-default 服务上。此服务指向 Golang 文件服务的 app Pod 中。在运行时,它为 ingress 控制器的根路径上的默认 Web 应用程序提供服务。如果需要更改此网页,我们只需要 edit/replace ConfigMap。

结语

容器编排的一个关键好处是,它承诺消除多个容器工作负载所需的“无差异的繁重工作”。通过使用 Kubernetes 声明性配置功能(如 ConfigMap),可以提高应用程序部署和更改集群状态的效率与速度。我们通过将 ConfigMap 资源作为已安装的卷,使用正在运行的容器,可以从容器中抽象配置和内容,减少对镜像重构和重新部署容器的需求。


以上所述就是小编给大家介绍的《K8S容器编排之ConfigMap 用于动态应用程序的实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Blog Design Solutions

Blog Design Solutions

Richard Rutter、Andy Budd、Simon Collison、Chris J Davis、Michael Heilemann、Phil Sherry、David Powers、John Oxton / friendsofED / 2006-2-16 / USD 39.99

Blogging has moved rapidly from being a craze to become a core feature of the Internetfrom individuals sharing their thoughts with the world via online diaries, through fans talking about their favori......一起来看看 《Blog Design Solutions》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具