您现在的位置是:首页 >学无止境 >研发工程师玩转Kubernetes——使用环境变量给容器中程序传递参数网站首页学无止境
研发工程师玩转Kubernetes——使用环境变量给容器中程序传递参数
简介研发工程师玩转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 |
参考资料
- https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/define-command-argument-container/
- https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/define-interdependent-environment-variables/
- https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/define-environment-variable-container/
- https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/environment-variable-expose-pod-information/
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。