ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
在 Node 上新创建一个 Pod 时,kubelet 会为每个 Pod(容器)添加一组环境变量,其中就包括当前系统中已经存在的 Service 的 IP 地址和端口号。 环境变量的格式如下所示: ~~~text {SVCNAME}_SERVICE_HOST=host {SVCNAME}_SERVICE_PORT=port ~~~ 环境变量名都必须为大写,如果其中有连字符的会被转换为下划线。 比如集群中已经存在一个名为`redis-master`的 Service,它在集群内的 IP 地址为:`10.0.0.11`,TCP 端口号为`6379`,那么新创建的 Pod 中就会被初始化一组环境变量如下所示: ~~~text REDIS_MASTER_SERVICE_HOST=10.0.0.11 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 ~~~ 所以环境变量在大部分情况下已经可以解决服务发现的问题了,但是这里存在一个需要注意的地方就是:服务必须先于 Pods 创建。如果先创建 Pods 后创建 Service,那么后创建的 Service 环境变量不会存在于先创建的 Pods 中。 下面我们来看一个实际的例子。 在`/home/shiyanlou`目录下新建`nginx-deployment.yaml`文件,并向其中写入如下内容: ~~~yaml apiVersion: apps/v1 kind: Deployment metadata: name: myweb spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 ~~~ 执行创建: ~~~bash $ kubectl create -f nginx-deployment.yaml deployment.apps/myweb created ~~~ 查看新创建的 Pods 的名称: ~~~bash $ kubectl get pods NAME READY STATUS RESTARTS AGE myweb-5754944d6c-8cngx 1/1 Running 0 5m56s myweb-5754944d6c-r27ld 1/1 Running 0 5m56s ~~~ 查看环境变量: ~~~bash $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 82d $ kubectl exec myweb-5754944d6c-8cngx env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=myweb-5754944d6c-8cngx # 可以看到 Pod 已经被初始化注册了 kubernetes 服务的相关环境变量 KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1 KUBERNETES_SERVICE_HOST=10.96.0.1 NGINX_VERSION=1.7.9-1~wheezy HOME=/root ~~~ 直接使用命令创建名为 myweb 的服务: ~~~bash $ kubectl expose deploy myweb service/myweb exposed ~~~ 查看 myweb Service 的集群 IP 和端口: ~~~bash $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 82d myweb ClusterIP 10.104.100.171 <none> 80/TCP 4s ~~~ 大家再一次执行`kubectl exec myweb-5754944d6c-8cngx env`(具体的 Pod 名称需要替换为你环境中的名称) 命令会发现新创建的服务在 myweb-5754944d6c-8cngx Pod 中依然也没有注册环境变量。这也就证实了我们前面提到的注意事项。 现在我们先新建名为 tomcat 的 Pod,观察新创建的 Pod 是不是初始化环境变量时就将 myweb Service 注册进去了呢? 在`/home/shiyanlou`目录下新建`tomcat-deployment.yaml`,并向其中写入如下内容: ~~~yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: selector: matchLabels: app: tomcat replicas: 2 template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: tomcat ports: - containerPort: 8080 ~~~ 执行创建: ~~~bash $ kubectl create -f tomcat-deployment.yaml deployment.apps/myapp created ~~~ 查看新创建的 Pods: ~~~bash $ kubectl get pods -l app=tomcat NAME READY STATUS RESTARTS AGE myapp-69ff6fc7c6-lm9mk 1/1 Running 0 10m myapp-69ff6fc7c6-rjr4f 1/1 Running 0 10m ~~~ 任选其中的一个 Pod 查看环境变量: ~~~bash $ kubectl exec myapp-69ff6fc7c6-lm9mk env|grep MYWEB MYWEB_PORT_80_TCP=tcp://10.104.100.171:80 MYWEB_PORT_80_TCP_PORT=80 MYWEB_PORT_80_TCP_ADDR=10.104.100.171 MYWEB_SERVICE_HOST=10.104.100.171 MYWEB_SERVICE_PORT=80 MYWEB_PORT=tcp://10.104.100.171:80 MYWEB_PORT_80_TCP_PROTO=tcp ~~~ 可以看到与 myweb 服务相关的环境变量都已经注册进了 tomcat Pod 中。 由于前面提到的环境变量的注意事项,所以更加推荐在服务发现中使用 DNS。