简体   繁体   English

将外部IP分配给Kubernetes服务

[英]Assign External IP to a Kubernetes Service

EDIT: The whole point of my setup is to achieve (if possible) the following : 编辑:我的设置的重点是实现(如果可能)以下内容:

  • I have multiple k8s nodes 我有多个k8s节点
  • When I contact an IP address (from my company's network), it should be routed to one of my container/pod/service/whatever. 当我联系IP地址(来自我公司的网络)时,它应该被路由到我的容器/ pod / service /中的任何一个。
  • I should be able to easily setup that IP (like in my service .yml definition) 我应该能够轻松设置IP(就像我的服务.yml定义)

I'm running a small Kubernetes cluster (built with kubeadm) in order to evaluate if I can move my Docker (old)Swarm setup to k8s. 我正在运行一个小的Kubernetes集群(用kubeadm构建),以评估我是否可以将Docker(旧)Swarm设置移动到k8s。 The feature I absolutely need is the ability to assign IP to containers, like I do with MacVlan. 我绝对需要的功能是能够为容器分配IP,就像我使用MacVlan一样。

In my current docker setup, I'm using MacVlan to assign IP addresses from my company's network to some containers so I can reach directly (without reverse-proxy) like if it's any physical server. 在我目前的docker设置中,我正在使用MacVlan将我公司网络中的IP地址分配给某些容器,这样我就可以直接到达(没有反向代理),就像它是任何物理服务器一样。 I'm trying to achieve something similar with k8s. 我正在努力实现与k8s类似的东西。

I found out that: 我发现:

  • I have to use Service 我必须使用服务
  • I can't use the LoadBalancer type, as it's only for compatible cloud providers (like GCE or AWS). 我不能使用LoadBalancer类型,因为它仅适用于兼容的云提供商(如GCE或AWS)。
  • I should use ExternalIPs 我应该使用ExternalIPs
  • Ingress Resources are some kind of reverse proxy ? Ingress Resources是某种反向代理?

My yaml file is : 我的yaml文件是:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
      name: nginx-deployment
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
      nodeSelector:
        kubernetes.io/hostname: k8s-slave-3
---
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  externalIPs: 
    - A.B.C.D

I was hopping that my service would get the IP ABCD (which is one of my company's network). 我跳的是我的服务将获得IP ABCD(这是我公司的网络之一)。 My deployment is working as I can reach my nginx container from inside the k8s cluster using it's ClusterIP . 我的部署工作正常,因为我可以使用它的ClusterIP从k8s集群内部到达我的nginx容器。

What am I missing ? 我错过了什么? Or at least, where can I find informations on my network traffic in order to see if packets are coming ? 或者至少,我在哪里可以找到有关网络流量的信息,以查看数据包是否即将到来?

EDIT : 编辑

$ kubectl get svc
NAME            CLUSTER-IP     EXTERNAL-IP       PORT(S)   AGE
kubernetes      10.96.0.1      <none>            443/TCP   6d
nginx-service   10.102.64.83   A.B.C.D           80/TCP    23h

Thanks. 谢谢。

If this is just for testing, then try 如果这仅用于测试,那么试试吧

kubectl port-forward service/nginx-service 80:80

Then you can 那么你也能

curl http://localhost:80

A solution that could work (and not only for testing, though it has its shortcomings ) is to set your Pod to map the host network with the hostNetwork spec field set to true . 可以工作的解决方案(不仅用于测试, 虽然它有其缺点 )是将Pod设置为映射主机网络,并将hostNetwork规范字段设置为true

It means that you won't need a service to expose your Pod, as it will always be accessible on your host via a single port (the containerPort you specified in the manifest). 这意味着您不需要服务来公开您的Pod,因为它总是可以通过单个端口(您在清单中指定的containerPort )在主机上访问。 No need to keep a DNS mapping record in that case. 在这种情况下,无需保留DNS映射记录。

This also means that you can only run a single instance of this Pod on a given node (talking about shortcomings...). 这也意味着您只能在给定节点上运行此Pod的单个实例(谈论缺点......)。 As such, it makes it a good candidate for a DaemonSet object. 因此,它使它成为DaemonSet对象的良好候选者。

If your Pod still needs to access/resolve internal Kubernetes hostnames, you need to set the dnsPolicy spec field set to ClusterFirstWithNoHostNet . 如果您的Pod仍然需要访问/解析内部Kubernetes主机名,则需要将dnsPolicy规范字段设置为ClusterFirstWithNoHostNet This setting will enable your pod to access the K8S DNS service. 此设置将使您的pod能够访问K8S DNS服务。

Example: 例:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx
spec:
  template:
    metadata:
      labels:
        app: nginx-reverse-proxy
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      tolerations:  # allow a Pod instance to run on Master - optional
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - image: nginx
        name: nginx
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443

EDIT: I was put on this track thanks to the the ingress-nginx documentation 编辑:感谢ingress-nginx文档,我被放在这条轨道上

You can just Patch an External IP 您可以只修补外部IP

CMD: $ kubectl patch svc svc_name -p '{"spec":{"externalIPs":["your_external_ip"]}}' CMD: $ kubectl patch svc svc_name -p '{"spec":{"externalIPs":["your_external_ip"]}}'

Eg:- $ kubectl patch svc kubernetes -p '{"spec":{"externalIPs":["10.2.8.19"]}}' 例如: - $ kubectl patch svc kubernetes -p '{"spec":{"externalIPs":["10.2.8.19"]}}'

First of all run this command: 首先运行此命令:

kubectl get -n namespace services

Above command will return output like this: 上面的命令将返回如下输出:

 NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
backend   NodePort   10.100.44.154         <none>          9400:3003/TCP   13h   
frontend        NodePort   10.107.53.39     <none>        3000:30017/TCP   13h

It is clear from the above output that External IPs are not assigned to the services yet. 从上面的输出可以清楚地看出,外部IP尚未分配给服务。 To assign External IPs to backend service run the following command. 要将外部IP分配给后端服务,请运行以下命令。

 kubectl patch svc backend -p '{"spec":{"externalIPs":["192.168.0.194"]}}'

and to assign external IP to frontend service run this command. 并将外部IP分配给前端服务运行此命令。

 kubectl patch svc frontend -p '{"spec":{"externalIPs":["192.168.0.194"]}}'

Now get namespace service to check either external IPs assignment: 现在获取命名空间服务以检查外部IP分配:

kubectl get -n namespace services

We get an output like this: 我们得到这样的输出:

NAME     TYPE     CLUSTER-IP     EXTERNAL-IP    PORT(S)             AGE
backend  NodePort 10.100.44.154  192.168.0.194  9400:3003/TCP       13h
frontend NodePort 10.107.53.39   192.168.0.194  3000:30017/TCP      13h

Cheers!!! 干杯!!! Kubernetes External IPs are now assigned . 现在已分配Kubernetes外部IP。

you can try kube-keepalived-vip configurtion to route the traffic. 你可以试试kube-keepalived-vip配置来路由流量。 https://github.com/kubernetes/contrib/tree/master/keepalived-vip https://github.com/kubernetes/contrib/tree/master/keepalived-vip

You can try to add "type: NodePort" in your yaml file for the service and then you'll have a port to access it via the web browser or from the outside. 您可以尝试在服务的yaml文件中添加“type:NodePort”,然后您将有一个端口通过Web浏览器或从外部访问它。 For my case, it helped. 对我而言,它有所帮助。

只需添加其他选项。

kubectl expose deployment hello-world --type=LoadBalancer --name=my-service --external-ip=1.1.1.1

I don't know if that helps in your particular case but what I did (and I'm on a Bare Metal cluster) was to use the LoadBalancer and set the loadBalancerIP as well as the externalIPs to my server IP as you did it. 我不知道在你的特定情况下是否有帮助,但我所做的(我在裸机群集上)是使用LoadBalancer并将loadBalancerIP以及externalIPs为我的服务器IP。

After that the correct external IP showed up for the load balancer. 之后,正确的外部IP出现在负载均衡器上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM