Kubernetes对外服务

Kuberntets介绍

Kubernets是一个Google主导的机群管理系统,目前底层可以使用Docker,实现Docker实例的应用编排。Kubernets的介绍很多,本文简单介绍安装和使用的过程。更多资料可参考Kerbernets官网

Kuberntets安装

Kubernets可以在虚拟机VM或安装Linux的服务器上安装,本文以Ubuntu Server服务器为例,详细可参见官网的Ubuntu安装指南

先下载Kubernets源码,目前最新版为1.4.1

本文中存在两个节点,node3(192.168.200.13)和node4(192.168.200.14),node3作为控制节点和计算节点,node4作为计算节点。于是修改kubernetes/cluster/ubuntu/config-default.sh

以上就是对配置文件的全部改动,请放置在相应位置。然后进行安装:

如果不出错则会提示安装完毕。此时将Kubernets的命令放于PATH中。

然后安装dashboard和dns组件:

可能存在的问题:

  • 如果需要重装,请运行KUBERNETES_PROVIDER=ubuntu ./kube-down.sh,停掉相关服务,然后要还原/etc/default/docker配置文件。
  • Kubernets会从Google的镜像仓库(gcr.io)获取某些镜像,但国内被墙了,所以可以选择一个http代理服务器,并在需要启动这些镜像的主机上为docker添加代理,方法是在/etc/default/docker中的开头添加:

然后重启docker:

完毕需要将代理去掉再重启docker,具体可参考这篇文章

确保所有需运行这些镜像的节点本地都要有这些镜像!!,可以先在一个节点上用代理下载所有镜像,然后上传到私有仓库,再在其他节点上下载这些镜像即可。

  • 在运行带有运行 google镜像时,如果本地已经有该镜像的时候,但配置文件中带有
    imagePullPolicy: Always
    时,则仍会从Google仓库去获取,一种方法是将其变为:

另一种方法是放到私有仓库中。
* 如果配置文件中没有指定imagePullPolicy,老版本会优先从本地找该版本的镜像,如有则直接启动;但发现1.4.1版本会优先pull。测试需要在配置文件中加入:

然后再运行安装或其他的命令。

  • Kubernetes会修改/etc/default/docker,请注意不要被覆盖原来的一些配置,否则docker pull私有仓库可能有问题,我的配置是:

Kubernets的一些概念

Pod

每一个Pod都是运行在某个节点上的实例或实例集合。可以对应于docker的实例或实例集合。
通过下面的命令可以查看运行的实例:

还可以看一些系统的实例:

还可以看这些pod运行在什么节点,这对排查问题比较有用。

Service

Service是提供对外可见的服务,可以使用下面的配置文件service.yaml新建服务。

可以用kubectl查看服务(svc是services的缩写):

正常情况下,在集群内部,是可以通过CLUSTER_IP : PORT来访问服务的,如在node3或node4上运行curl http://100.0.34.47:18111来访问django-x的服务的。

CLUSTER是Kubernets内部维护的机群,所以CLUSTER-IP和PORT是服务面向集群提供的内部ip和端口,互联网是访问不到的,例如上面的kubernets和basic服务就是这种情况。如果要从互联网访问这些服务,我们会在下面讲到,可用ingress的方法,使用一个代理将请求转到CLUSTER-IP : PORT。

如果每个物理节点是互联网可以直接访问到的话,那么也可以使用NodePort的类型,如上面的三个django都是这类服务,所以其外部IP是nodes。这样每个节点上的kube-proxy服务都会开一个端口P,外部网络可以通过访问任意一个节点的端口P进行访问。
那么P如何获得呢?可以通过查询服务获知:

那么就可以通过curl http://192.168.200.13:32400来访问该服务了。

Replication Controller

Replication Controller(RC)是控制Pod数量和部署的控制器,Kubernets区别原生Docker很重要的一点是它实现了对资源的监控、弹性部署。假设一个pod挂了,rc可以再启动一个;或者机群要扩容,rc也可以很快增加pod实现。

以下配置文件rc.yaml可以新建三个RC:

如果要获取rc,可运行:

可能存在的问题
* 当要查看某个pod、service或rc的详细信息,可以用describe。如某个pod挂了,可以详细查看具体日志:

其中kube-dns看似有问题,继续检查:

能看到是因为向google的仓库下载超时导致的,可参考上面的代理方法解决。

比如现在我需要运行一个django的web服务,那么可以通过运行下面的配置文件即可实现。

为Service添加互联网入口

Load balance

可以expose deployment(带–type=”LoadBalance”)的方式将服务暴露出去,但是目前这种方式支持公有云,如Google Container Engine等,貌似不能应用于私有的数据中心。具体可以参考官网Hello World的Allow external traffic一节

Ingress

在内网部署服务,希望对外暴露,可以使用Ingress的方式,以下配置文件为将上述服务在80端口上做映射,实现虚拟主机的功能。

然后运行并查看Ingress

Ingress是Kubernets的一种用于访问服务的机制,可以通过api获得这些映射关系,不过如何实现具体的功能,例如上例中的虚拟主机功能,可以使用Kubernets的contrib中的ingress-controller实现,本文给出的是使用nginx实现。

contrib是一大堆未进入Kubernets核心的代码集合,代码在(https://github.com/kubernetes/contrib),安装请按照项目的README进行(需要在$GOPATH里面,不是随便安装即可的),假设$GOPATH=/usr/src/gohome,那么Kubernets Contrib在/usr/src/gohome/src/k8s.io/contrib/,而我们说的nginx Ingress控制器则在/usr/src/gohome/src/k8s.io/contrib/ingress/controllers/nginx-alpha。

查看一下nginx-alpha目录下面的rc.yaml可知,Ingress Controller后台使用了gcr.io/google_containers/nginx-ingress镜像,不过这个镜像在笔者测试时有问题,所以实验中还是根据同目录下的Dockerfile重新生成的。查看Dockerfile可知,这个镜像是基于nginx的,并通过运行controller程序将Kubernets API获得的Ingress映射翻译成nginx的配置文件,从而实现了反向代理到运行不同网站的Service的功能。

当运行完创建rc.yaml后,我们可以找到相应的docker容器,观察其中的映射规则:

到此为止,背后的原理已经清楚了。我们可以看一下运行效果。因为三个服务运行的都是django,所以可以查看django的输出日志(如果用supervisor运行的,可以进容器查看/var/log/supervisor里面相关的log文件)查看真实的Web访问情况。

此时,如果访问http://bar.baz.com/bar,就会转到django-y的服务(http://django-y.default.svc.cluster.local:18111),如果访问http://bar.baz.com/foo或http://foo.bar.com/foo,就转到django-x,其余的则转到ngix的404页面。

上述思路不仅可以使用在web服务,还可以用于如外部接入ssh等。

Leave a Comment

Your email address will not be published. Required fields are marked *