gpt4 book ai didi

google-cloud-platform - 通过kubernetes单节点集群创建服务不会给我 'ingress'外部IP,但是Google容器引擎可以(?)

转载 作者:行者123 更新时间:2023-12-02 12:23:59 26 4
gpt4 key购买 nike

我正在尝试为演示和测试目的设置一个单节点kubernetes集群,我希望它能够表现
就像一个“成熟的” k8s集群(例如Google容器引擎)。我的客户有自己的k8s安装,
在此讨论中,我们可以假定行为与Google容器引擎的k8s安装非常相似。

在成熟的K8s上获取入口IP

我正在创建一个wordpress pod并将其作为服务公开,如本教程中所述:
https://cloud.google.com/container-engine/docs/tutorials/hello-wordpress

如果您想复制问题,只需复制以下命令即可,我从教程中取消了这些命令:
(这是假设您有一个名为“stellar-access-117903”的项目。如果没有,请设置为您的Google Container的名称
引擎项目。)

# set up the cluster  (this will take a while to provision)
#
gcloud config set project stellar-access-117903
gcloud config set compute/zone us-central1-b
gcloud container clusters create hello-world \
--num-nodes 1 \
--machine-type g1-small

# Create the pod, and expose it as a service
#
kubectl run wordpress --image=tutum/wordpress --port=80
kubectl expose rc wordpress --type=LoadBalancer

# Describe the service
kubectl describe services wordpress

describe命令的输出包含“LoadBalancer Ingress:{some-ip-address}”行,该行是
正是我所期望的。现在,当我对单节点群集设置执行相同的操作时,我不会
得到那条线。我可以在显示在输出中的IP上点击wordpress服务
'描述服务'命令。。但是在“单节点”模式下,打印出的IP是>群集IP <
服务(通常据我所知)通常无法公开访问。由于某种原因
在单节点模式下可公开访问。我们可以按照以下步骤进行复制。

不在单节点K8s上获取入口IP

首先设置单节点k8s,如本教程中所述:
https://github.com/kubernetes/kubernetes/blob/master/docs/getting-started-guides/docker.md

为了易于重现,我提供了以下所有命令,因此您只需复制/粘贴即可:
K8S_VERSION=1.1.1

sudo docker run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data


sudo docker run \
--volume=/:/rootfs:ro \
--volume=/sys:/sys:ro \
--volume=/dev:/dev \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
--volume=/var/run:/var/run:rw \
--net=host \
--pid=host \
--privileged=true \
-d \
gcr.io/google_containers/hyperkube:v${K8S_VERSION} \
/hyperkube kubelet --containerized --hostname-override="127.0.0.1" --address="0.0.0.0" --api-servers=http://localhost:8080 --config=/etc/kubernetes/manifests

sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube proxy --master=http://127.0.0.1:8080 --v=2


# set your context to use the locally running k8s API server
#
kubectl config set-cluster dev --server=http://localhost:8080
kubectl config set-context dev --cluster=dev --namespace=$NS
kubectl config use-context dev

现在,执行与针对Google Container Engine的k8s相同的命令
# Create the pod, and expose it as a service
#
kubectl run wordpress --image=tutum/wordpress --port=80
kubectl expose rc wordpress --type=LoadBalancer

# Describe the service
kubectl describe services wordpress

最后一条命令的输出(您将看不到“Ingress”信息)为:
Name:           wordpress
Namespace: default
Labels: run=wordpress
Selector: run=wordpress
Type: LoadBalancer
IP: 10.0.0.61
Port: <unnamed> 80/TCP
NodePort: <unnamed> 31795/TCP
Endpoints: 172.17.0.30:80
Session Affinity: None
No events.

在Google容器引擎的k8s中,我看到诸如“正在创建负载均衡器”,“已创建负载均衡器”之类的事件。但是没有什么比
发生在单节点实例中。

我想知道...我需要做一些配置以使它们相同地工作吗?他们很重要
工作方式相同...仅在可扩展性方面有所不同,因为我们要针对单节点版本运行测试,并且
如果它的行为不同,将会非常令人困惑。

在此先感谢您的帮助
-克里斯

最佳答案

这是我们想出的解决方案。当我们在单节点Kubernetes上运行时,我们通过反复试验意识到,当您公开服务时,外部IP不会通过IngressIP返回。而是通过clusterIP返回,如上所述,clusterIP是公开可见的。因此,我们只修改了代码即可使用。我们在单节点情况下使用clusterIP。这是我们用来在服务上建立监视的代码,以确定k8s何时分配了我们的外部可见IP:

首先,我们使用fabric8 API创建服务配置:

            case "Service" =>
val serviceConf = mapper.readValue(f, classOf[Service])
val service = kube.services().inNamespace(namespaceId).create(serviceConf)
watchService(service)

'watchService'方法定义如下:
  private def watchService(service: Service) = {
val namespace = service.getMetadata.getNamespace
val name = service.getMetadata.getName
logger.debug("start -> watching service -> namespace: " + namespace + " name: " + name)
val kube = createClient()
try {
@volatile var complete = false
val socket = kube.services().inNamespace(namespace).withName(name).watch(new Watcher[Service]() {
def eventReceived(action: Action, resource: Service) {
logger.info(action + ":" + resource)
action match {
case Action.MODIFIED =>
if (resource.getMetadata.getName == name) {
complete = isServiceComplete(resource)
}
// case Action.DELETED =>
// complete = true
case _ =>
}
}
})
while (!complete) {
Thread.sleep(5000)
complete = isServiceComplete(kube.services().inNamespace(namespace).withName(name).get)
}
logger.info("Closing socket connection")
socket.close()
} finally {
logger.info("Closing client connection")
kube.close()
}

logger.debug("complete -> watching services , namespace: " + namespace + " name: " + name)
}

我们介绍的主要技巧是在方法“isServiceComplete”中。当使用单节点k8s时,“isUsingMock”的值为true。这样就可以使用clusterIP来确定服务配置是否已完成。
  private def isServiceComplete(service: Service) = {
!service.getStatus.getLoadBalancer.getIngress.isEmpty || mockServiceComplete(service)
}

def mockServiceComplete(service: Service): Boolean = {
val clusterIP = service.getSpec.getClusterIP
logger.trace(s"mockServiceComplete: $isUsingMock / $clusterIP / $KUBE_SERVER" )
isUsingMock && ! clusterIP.isEmpty
}

抱歉,如果这里没有很多额外的上下文。最终,我们的项目应该是开源的,我们可以发布完整的解决方案。

-克里斯

关于google-cloud-platform - 通过kubernetes单节点集群创建服务不会给我 'ingress'外部IP,但是Google容器引擎可以(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34574511/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com