行至水穷处

坐看云起时

K8s 1.6.7安装F5 k8s-bigip-ctlr(F5 Container Connector,F5 CC)

CC简介

前面安装部署了k8s集群环境,看上去工作正常,下一步在k8s内安装F5公司发布的container connector,也叫F5 CC。CC是一个开源的F5产品,主要目的是通过在k8s集群内运行一个k8s-bigip-ctlr pod实例,通过定义一个config map实现将k8s的service或者pod配置到F5 BIGIP产品上,实现集群环境内业务南北向流量的外部发布,从而实现对业务的对外发布并充分利用F5 BIGIP产品的丰富功能,例如LB,SSL,WAF,火墙,抗DDOS等。

CC通过监控相关API接口获取信息,根据定义的标签为F5type: virtual-server Configmap定义文件通过F5 BIGIP的RESTful接口对F5 BIGIP进行自动化配置。k8s内部的service的变化可以自动化的反应到BIGIP的配置上,例如service的增改删,扩容缩减等。

具体cc产品,可参考官方文档http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest/

基于已安装好的K8S 1.6.7环境安装CC

  1. 在master节点上创建一个secret以供cc容器在连接bigip设备时候使用, 替换用户名和密码为实际设备的
  2. 使用官方提供的yaml文件部署cc

    如果顺利的话,你会发现这个pod是失败的:),此时可以通过dashboard上查看pod的log,或者通过查看pod所mount的本地文件查看log(docker inpsect 容器名可以查看,io.kubernetes.container.logpath 项的值,类似/var/log/pods/b47ba7e6-6ba0-11e7-bdc9-000c29420d98/k8s-bigip-ctlr_0.log),或者使用kubectl logs命令查看,会发现cc提示如下文件或目录找不到的错误:
    /var/run/secrets/kubernetes.io/serviceaccount/token


    这是由于在api的启动配置中设置了–admission-control=AlwaysAdmit. F5 CC使用https与api通信,需要serviceaccount plugin的支持,因此需要在准入控制里明确启用servcieaccount,即改为
    --admission-controlNamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
  3. 修改上述准入控制后,重启APIserver, 并重新部署cc,发现deployment可以成功,但是产生的replica set会报如下错误从而无法产生pod

    这是由于目前整个集群配置还没有给配置SSL证书,系统要要为这些serviceaccount产生对应secret,需要集群整体使用SSL配置,因此要用相关CA来产生签名,可以自己产生一个CA,并为apiserver产生相关证书(实际上apiserver在未指定证书情况下,自己本身会产生一张证书/var/run/kubernetes/apiserver.crt 和apiserver.key), 这里采用自己创建的方式,具体步骤见这里
  4. 创建所有证书,修改master上所有组件启动配置,并重启服务后,可以看到系统自动产生了很多default secrets(controller server必须配置好相关与证书有关的flag重启后才可以看到这些secret,这些secret里都包含了ca.crt)
  5. 此时再查看cc相关的pod已经正常起来,不再有上面第3步中的错误,但是此时cc容器还是没有正常工作,查看其日志,可以看到一直报如下日志:

    这是因为在1.6.7的RBAC授权模式下,default没有权限。
  6. 因此需要再创建pod时候指定一个ServiceAccount,并将该SA与clusterrole进行绑定以提供权限
    A: 创建SA

    kubectl create -f f5-servcie-account.yaml

    执行完毕后,系统自动为该sa创建一个secret:

    B: 执行角色绑定,来给f5bigip这个SA授权

    kubectl create -f f5-sa-cluster-role-binding.yaml
    执行后检查相关绑定:

  7. 修改官方cc deployment文件,增加serviceAcountName配置:

    由于之前已create了,这里重新apply修改后的yaml, kubectl apply -f f5-k8s-bigip-ctlr.yaml,再查看cc pod,发现已正常运行, 日志如下:
    [root@docker1 f5]# kubectl logs k8s-bigip-ctlr-deployment-4170992206-mckz7 -n kube-system
    2017/07/18 14:49:16 [INFO] ConfigWriter started: 0xc4200c56b0
    2017/07/18 14:49:16 [INFO] Started config driver sub-process at pid: 10
    2017/07/18 14:49:16 [INFO] NodePoller (0xc420413980) registering new listener: 0x405d70
    2017/07/18 14:49:16 [INFO] NodePoller started: (0xc420413980)
    2017/07/18 14:49:16 [INFO] ProcessNodeUpdate: Change in Node state detected
    2017/07/18 14:49:16 [INFO] Wrote 0 Virtual Server configs
    2017/07/18 14:49:18 [INFO] [2017-07-18 14:49:18,068 __main__ INFO] entering inotify loop to watch /tmp/k8s-bigip-ctlr.config036477452/config.json

 

与BIGIP联动测试

  1. BIGIP要与k8s在网络上路由可达,这里使用service所发布的网络与BIGIP互联
  2. BIGIP上要提前配置好自定义的partition,该partition名称在上述cc部署文件里已指定为 kubernetes
  3. k8s内要先启动一个业务service,这里以nginx为例:
  4. 创建一个F5 configmap

    执行 kubectl create -f f5-vs-config.yaml
  5. 检查F5 BIGIP已产生配置
  6. nodeport方式下扩容、缩减测试
    首先检查当前的deployment只要求部署一个pod实例,为什么在BIGIP上产生两个node节点的IP(测试环境是1master+2 nodes),这是因为当前以nodeport模式配置BIGIP,而k8s在发布nodeport的service时候是所有node节点都会产生一个本地port并通过iptables实现内部node间流量的LB的,因此F5有必要加入所有node地址以防止局部节点失效。因此在nodeport模式下,pool member永远是等于实际node数量的,不管pod实例是多于node数量还是少于node数量,这里实际数据path是: client–》F5bigip–》nodeip:nodeport–》k8s service内部LB
  7. clusterIP方式加扩容,缩减测试
    A 修改CC 部署模式为cluster方式

    B 修改完毕保存后,直接查看F5 BIGIP,发现配置已经修改为pod的IP,且只有一个IP,这是因为当前nginx的部署只配置启动一个pod实例

    C 扩容nginx实例

    kubectl scale --replicas=3 deploy/k8s-nginx
    查看F5配置变化,已变为3个IP:

    这种方式下,BIGIP需要能够直接访问到pod的网络

 

看上去折腾了半天,那么用CC的好处是什么?直接写程序获取APIserver输出,然后通过F5的Restful接口来更新配置不就可以了么?欢迎深入讨论。

目前CC通过configmap来对F5的配置参数还比较有限,不过CC本身是开源的,https://github.com/F5Networks/k8s-bigip-ctlr 有兴趣的话可以再开发复杂功能。

目前configmap定义中还不能引用svc的label,这限制了一些灵活性,比如如果希望将某些带有特殊label的svc配置到某个独立的BIGIP上,则当前不能在一个configmap就完成,

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注