您现在的位置是:首页 >学无止境 >研发工程师玩转Kubernetes——使用环境变量给容器中程序传递参数网站首页学无止境

研发工程师玩转Kubernetes——使用环境变量给容器中程序传递参数

breaksoftware 2024-06-21 18:01:02
简介研发工程师玩转Kubernetes——使用环境变量给容器中程序传递参数

《研发工程师玩转Kubernetes——构建、推送自定义镜像》中,Pod的IP是通过代码获取的

def get_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
        return ip

实际我们可以在清单文件中,通过环境变量将该值传递给容器中的程序。

让程序接受环境变量

我们对程序进行相关改造

from http.server import HTTPServer, BaseHTTPRequestHandler
import argparse
import os
 
version = 0

class Resquest(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        data = "This service's version is {0}
IP is:{1}".format(version, os.environ.get("POD_IP", ""))
        self.wfile.write(data.encode())
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('-port', metavar='N', type=int, help='port of service', required=True)
    parser.add_argument('-version', metavar='N', type=int, help='version of service', required=True)
    args = parser.parse_args()
    version = args.version
    host = ('0.0.0.0', args.port)
    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: {0}:{1}".format(os.environ.get("POD_IP", ""), args.port))
    server.serve_forever()

IP是通过os.environ.get(“POD_IP”, “”)获取。
在这里插入图片描述
为了充分展现kubernetes的功能,我们还对Dockerfile做了修改,删除了镜像自动执行命令的指令。这样镜像仅仅是环境,不涉及任何运行操作。
在这里插入图片描述

生成并推送镜像

这些环境准备好后,我们生成镜像并推送

docker build -t simple_http:v3 .
Sending build context to Docker daemon  16.25MB
Step 1/5 : From python:3.11
 ---> 815c8c75dfc0
Step 2/5 : RUN pip install --upgrade pip
 ---> Using cache
 ---> e26af84d8b3e
Step 3/5 : COPY requirements.txt /requirements.txt
 ---> Using cache
 ---> 9e14379efd70
Step 4/5 : RUN pip install -r /requirements.txt
 ---> Using cache
 ---> 964f97edf3b5
Step 5/5 : COPY main.py /main.py
 ---> f84ff4a7c50d
Successfully built f84ff4a7c50d
Successfully tagged simple_http:v3
docker tag simple_http:v3 localhost:32000/simple_http:v3
docker push localhost:32000/simple_http:v3
The push refers to repository [localhost:32000/simple_http]
e332834a526b: Pushed 
dff24bf5a998: Layer already exists 
288d113a8d9c: Layer already exists 
91d4152a99e8: Layer already exists 
889828f94722: Layer already exists 
b0f747a5176b: Layer already exists 
7dac77253a2b: Layer already exists 
0007505dc811: Layer already exists 
f43725f97b9f: Layer already exists 
9c42af2c6418: Layer already exists 
d96e248f10e6: Layer already exists 
d925e0fae4e6: Layer already exists 
v3: digest: sha256:b38b4baddca283822da1fe70276708a28a7e6fb807fb934e086be01d14da9626 size: 2841

部署

参考《研发工程师玩转Kubernetes——使用Deployment进行多副本维护》,我们使用Deployment部署镜像。
我们会对清单文件做响应修改:

  • 新增启动程序的命令command
  • 新增环境变量env
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-http-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple_http
  template:
    metadata:
      labels:
        app: simple_http
    spec:
      containers:
      - name: simple-http-container
        image: localhost:32000/simple_http:v3
        ports:
        - containerPort: 8888
        command: ["python","main.py","-port","$(SERVER_PORT)","-version","3"]
        env:
        - name: SERVER_PORT
          value: "8888"
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

在这里插入图片描述
可以看到之前在Dockerfile中的启动程序指令被搬到清单文件中。
比较特殊的是参数中的port值,我们使用了env中的自定义的字段SERVER_PORT——在命令(command)中要使用$(SERVER_PORT)表达。

        - name: SERVER_PORT
          value: "8888"

env中还定义了一个字段POD_IP,它表示Deployment创建的Pod的IP。由于这个IP是在Pod创建后确定的,我们就需要使用status.podIP来表达它。

        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP

然后我们使用下面命令创建该Deployment

kubectl create -f simple_http_deployment.yaml

deployment.apps/simple-http-deployment created

检查

使用kubectl describe pod来获取pod信息

Name:             simple-http-deployment-69579df7b8-zkjz7
Namespace:        default
Priority:         0
Service Account:  default
Node:             fangliang-virtual-machine/192.168.137.248
Start Time:       Wed, 24 May 2023 00:06:37 +0800
Labels:           app=simple_http
                  pod-template-hash=69579df7b8
Annotations:      cni.projectcalico.org/containerID: d103d97a8b9506fa4aa8b2172cf889f02874d02cb6cbe24dab1ee9c4f07dc2dd
                  cni.projectcalico.org/podIP: 10.1.62.179/32
                  cni.projectcalico.org/podIPs: 10.1.62.179/32
Status:           Running
IP:               10.1.62.179
IPs:
  IP:           10.1.62.179
Controlled By:  ReplicaSet/simple-http-deployment-69579df7b8
Containers:
  simple-http-container:
    Container ID:  containerd://a3d6a26a85a4e9476fa182fce0b350a4f6893cdd63b4b9f72e293b95a0d336c9
    Image:         localhost:32000/simple_http:v3
    Image ID:      localhost:32000/simple_http@sha256:b38b4baddca283822da1fe70276708a28a7e6fb807fb934e086be01d14da9626
    Port:          8888/TCP
    Host Port:     0/TCP
    Command:
      python
      main.py
      -port
      $(SERVER_PORT)
      -version
      3
    State:          Running
      Started:      Wed, 24 May 2023 00:06:38 +0800
    Ready:          True
    Restart Count:  0
    Environment:
      SERVER_PORT:               8888
      POD_IP:                     (v1:status.podIP)
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7sq6n (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-7sq6n:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:                      <none>


Name:             simple-http-deployment-69579df7b8-mfsvh
Namespace:        default
Priority:         0
Service Account:  default
Node:             fangliang-virtual-machine/192.168.137.248
Start Time:       Wed, 24 May 2023 00:06:37 +0800
Labels:           app=simple_http
                  pod-template-hash=69579df7b8
Annotations:      cni.projectcalico.org/containerID: fd14cd14683f59d10fc562e6ae829c30d1b654436670a149f093c12a596bc5fa
                  cni.projectcalico.org/podIP: 10.1.62.182/32
                  cni.projectcalico.org/podIPs: 10.1.62.182/32
Status:           Running
IP:               10.1.62.182
IPs:
  IP:           10.1.62.182
Controlled By:  ReplicaSet/simple-http-deployment-69579df7b8
Containers:
  simple-http-container:
    Container ID:  containerd://2dccf799cfff5d7fad3ea033bba837acab06f9738933cd87cf7a689588f9164a
    Image:         localhost:32000/simple_http:v3
    Image ID:      localhost:32000/simple_http@sha256:b38b4baddca283822da1fe70276708a28a7e6fb807fb934e086be01d14da9626
    Port:          8888/TCP
    Host Port:     0/TCP
    Command:
      python
      main.py
      -port
      $(SERVER_PORT)
      -version
      3
    State:          Running
      Started:      Wed, 24 May 2023 00:06:38 +0800
    Ready:          True
    Restart Count:  0
    Environment:
      SERVER_PORT:               8888
      POD_IP:                     (v1:status.podIP)
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-l2cqd (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-l2cqd:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:                      <none>

我们可以看到清单文件中的信息在这儿都得到了体现,比如Command和Environment字段。
访问任意一个Pod的服务,可以看到结果是正常的。
在这里插入图片描述

其他参数和设置方法

名字写法值例子
Pod的名称- name: POD_NAME
valueFrom:
fieldRef:
          fieldPath: metadata.name
simple-http-deployment-69579df7b8-mfsvh
Pod的IP- name: POD_IP
valueFrom:
fieldRef:
          fieldPath: status.podIP
10.1.62.182
Pod所在的命名空间- name: POD_NAMESPACE
valueFrom:
fieldRef:
          fieldPath: metadata.namespace
default
Pod所在Node的名称- name: NODE_NAME
valueFrom:
fieldRef:
          fieldPath: spec.nodeName
fangliang-virtual-machine
Pod所在Node的IP- name: HOST_IP
valueFrom:
fieldRef:
          fieldPath: status.hostIP
192.168.137.248

参考资料

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。