我有两个Java微服务( caller.jar ,它会调用 Called.jar )
我们可以通过 env-var CALLERPORT 设置 caller 服务的http端口,并通过env-var < em> CALLEDADDRESS 。 因此呼叫者使用了两个env-var。
我们还必须设置被调用服务env-var CALLEDPORT ,以便设置被调用服务正在侦听HTTP请求的特定http端口。
我不知道如何确切地从Dockerfile中公开这些变量,以便使用Kubernetes进行设置。
这是我制作两个Dockerfile的方法:
调用方的Dockerfile
FROM openjdk:8-jdk-alpine
# ENV CALLERPORT (it's own port)
# ENV CALLEDADDRESS (the other service address)
ADD caller.jar /
CMD ["java", "-jar", "caller.jar"]
被调用的Dockerfile
FROM openjdk:8-jdk-alpine
# ENV CALLEDPORT (it's own port)
ADD called.jar /
CMD ["java", "-jar", "called.jar"]
借助这些,我制作了两个 Docker映像:
然后我做了两个Deployment.yaml,以便让K8s使用副本和负载平衡器部署(在minikube上)两个微服务。
deployment-caller.yaml
apiVersion: v1
kind: Service
metadata:
name: caller-loadbalancer
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: caller
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: caller
labels:
app: caller
spec:
replicas: 2
minReadySeconds: 15
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: caller
tier: caller
strategy:
type: Recreate
template:
metadata:
labels:
app: caller
tier: caller
spec:
containers:
- image: myaccount/caller
name: caller
env:
- name: CALLERPORT
value: "8080"
- name: CALLEDADDRESS
value: called-loadbalancer # WHAT TO PUT HERE?!
ports:
- containerPort: 8080
name: caller
和部署称为.yaml
apiVersion: v1
kind: Service
metadata:
name: called-loadbalancer
spec:
type: LoadBalancer
ports:
- port: 8081
targetPort: 8081
selector:
app: called
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: called
labels:
app: called
spec:
replicas: 2
minReadySeconds: 15
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: called
tier: called
strategy:
type: Recreate
template:
metadata:
labels:
app: called
tier: called
spec:
containers:
- image: myaccount/called
name: called
env:
- name: CALLEDPORT
value: "8081"
ports:
- containerPort: 8081
name: called
重要提示: 如果单独调用单个服务(例如调用运行状况检查终结点),则可以很好地工作,但是,当调用涉及两个服务之间的通信的终结点时,就会出现此错误:
java.net.UnknownHostException:称为
pod已正确运行且处于活动状态,但是我想问题是Deployment.yaml的一部分,在其中必须定义如何查找指向的服务,所以在这里:
spec:
containers:
- image: myaccount/caller
name: caller
env:
- name: CALLERPORT
value: "8080"
- name: CALLEDADDRESS
value: called-loadbalancer # WHAT TO PUT HERE?!
ports:
- containerPort: 8080
name: caller
都不是
called
也
called-loadbalancer
也不
http://caller
kubectl get pods,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/called-855cc4d89b-4gf97 1/1 Running 0 3m23s 172.17.0.4 minikube <none> <none>
pod/called-855cc4d89b-6268l 1/1 Running 0 3m23s 172.17.0.5 minikube <none> <none>
pod/caller-696956867b-9n7zc 1/1 Running 0 106s 172.17.0.6 minikube <none> <none>
pod/caller-696956867b-djwsn 1/1 Running 0 106s 172.17.0.7 minikube <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/called-loadbalancer LoadBalancer 10.99.14.91 <pending> 8081:30161/TCP 171m app=called
service/caller-loadbalancer LoadBalancer 10.107.9.108 <pending> 8080:30078/TCP 65m app=caller
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 177m <none>
如果将放在Deployment.yaml的这一行中,则可以使用。 那么在这一行中要放什么呢?
答案 0 :(得分:4)
简短的答案是,您不需要在Dockerfile中公开它们。您可以在启动容器时设置所需的任何环境变量,而不必在Dockerfile中预先指定它们。
您可以通过使用“ docker run”,“-e”设置环境变量和“ -it”来获得交互式会话来启动容器,从而验证这一点。回显您的env var的值,您将看到它已设置。
您还可以使用'kubectl exec'(https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/)与正在运行的kubernetes Pod中的一个容器进行终端会话。从那里您可以从那里回显环境变量以查看它们是否已设置。在使用“ kubectl get pods”获得豆荚名称后,您可以使用“ kubectl describe pod”更快地查看它们。
由于遇到问题,您还想检查服务是否正常运行。由于您使用的是minikube,因此您可以执行“ minikube服务”来检查它们是否可以从外部访问。您还需要检查内部访问权限-参见Accessing spring boot controller endpoint in kubernetes pod
您使用服务名称和端口的方法是有效的。进行一些调试,您应该就能使其工作。您的设置类似于我在https://dzone.com/articles/kubernetes-namespaces-explained中所做的说明,因此引用可能会有所帮助(除非您直接使用env vars而不是通过configmap来使用,但等同)。
我认为,在调用方中,您将错误的端口注入到env var中-您是在放置调用方自己的端口,而不是尝试调用的端口。
答案 1 :(得分:1)
要访问Kubernetes内部的服务,您应该使用以下DNS:
答案 2 :(得分:1)
首先-完全不可能理解您想要什么。您的帖子开始于:
我们可以设置...
我们必须设置...
这里没有人不知道您想做什么,而查看您期望完成的一些定义可能会更有用。
现在已经说了这一点,我必须转向您的实质性问题...
env:
- name: CALLERPORT
value: "8080"
- name: CALLEDADDRESS
value: called-loadbalancer # WHAT TO PUT HERE?!
ports:
- containerPort: 8080
name: caller
这东西将由k8s自动导出。例如,我在服务定义中有一个kibana
服务port:80
:
svc/kibana ClusterIP 10.222.81.249 <none> 80/TCP 1y app=kibana
这是我如何在同一名称空间中的不同pod中获得此消息的方法:
root@some-pod:/app# env | grep -i kibana
KIBANA_SERVICE_PORT=80
KIBANA_SERVICE_HOST=10.222.81.249
前进,为什么要使用LoadBalancer?没有任何云,它将类似于NodePort,但似乎ClusterIP就是您所需要的。 接下来,服务端口可以相同,并且不会发生任何端口冲突,因为ClusterIP每次都是唯一的,因此套接字对于每个服务都是唯一的。您的服务可以这样描述:
apiVersion: v1
kind: Service
metadata:
name: caller-loadbalancer
spec:
type: LoadBalancer
ports:
- port: 80 <--------------------
targetPort: 8080
selector:
app: caller
apiVersion: v1
kind: Service
metadata:
name: called-loadbalancer
spec:
type: LoadBalancer
ports:
- port: 80 <------------------
targetPort: 8081
selector:
app: called
这将简化服务名称的使用,而无需指定端口:
http://caller-loadbalancer.default.svc.cluster.local
http://called-loadbalancer.default.svc.cluster.local
或
http://caller-loadbalancer.default
http://called-loadbalancer.default
或(在类似的名称空间内):
http://caller-loadbalancer
http://called-loadbalancer
或(取决于lib)
caller-loadbalancer
called-loadbalancer
关于containerPort / targetPort的一些事情!为什么使用8081
和8080
?谁在乎内部集装箱港口?我同意会发生不同的情况,但是在这种情况下,您内部只有一个进程,并且您肯定不会在那里运行更多的进程,是吗?因此它们也可以相同。
我想建议您以不同的方式使用stackoverflow。不要问如何按照自己的方式做事,最好不要问如何以最好的方式做事