之前简单分析过Kong ingress controller的实现、使用、CRD。这里稍微规整一下。
2019-05-06 16:28:56:kong 1.1.x有了一个重大变换,实现了db-less模式,可以不使用数据库了,见笔记二十六:查看全部笔记。
如果是刚开始学习kong,直接从1.x开始,0.x已经不再维护,0.15是0.x的最后一个版本。
前19篇笔记是刚开始接触kong时记录的,使用的版本是0.14.1,当时对kong一知半解,笔记比较杂乱。第二十篇开始是再次折腾时的笔记,使用的版本是1.0.3,笔记相对条理一些。
从0.x到1.x需要关注的变化有:
Kong ingress controller项目名是kubernetes-ingress-controller,是一个独立于kong的项目。最新release版本是0.3.0,适配kong 1.0.x。项目中提供了部署yaml。
编译命令如下:
make deps //需要翻Q
make build
make container //打包镜像
默认生成的是ELF格式的Linux可执行文件,如果要生成其它格式的可执行文件,用GOOS指定系统类型:
make build GOOS=darwin
依赖包用dep命令管理,项目代码需要在GOPATH/src目录下,如果不愿把代码在src目录中,可以在src目录中做一个符号链接,连接到位于其它位置的代码目录。如果项目不在GOPATH/src中,会报下面的错误:
$ make deps
dep ensure -v -vendor-only
/Users/lijiao/Work/kong-ingress-controller is not within a known GOPATH/src
make: *** [deps] Error 1
可以建一个符号链接解决:
ln -s `pwd`/kong-ingress-controller $GOPATH/src/github.com/Kong/kubernetes-ingress-controller
cd $GOPATH/src/github.com/Kong/kubernetes-ingress-controller
make deps
make deps
依赖的一些代码在Q内不能访问,需要翻qiang,否则可能会爆下面的错误:
grouped write of manifest, lock and vendor: error while writing out vendor tree: failed to write dep tree:
failed to export cloud.google.com/go: unable to deduce repository and source type for "cloud.google.com/go":
unable to read metadata: unable to fetch raw metadata: failed HTTP request to URL "http://cloud.google.com/go?go-get=1":
Get http://cloud.google.com/go?go-get=1: dial tcp 172.217.160.110:80: i/o timeout
make: *** [deps] Error 1
make deps
在安装Go deps的时候如果出现下面的错误,可能是因为系统上有多个不同版本的go命令,用到的go命令与GOROOT指定的路径不匹配:
go get github.com/golang/dep/cmd/dep
# errors
# errors
compile: version "go1.12.1" does not match go tool version "go1.12"
# internal/race
compile: version "go1.12.1" does not match go tool version "go1.12"
# unicode/utf8
compile: version "go1.12.1" does not match go tool version "go1.12"
...
make build
将编译得到的文件存放在/var/folders/c_.....
目录中:
$ make build
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -installsuffix cgo \
-ldflags "-s -w -X github.com/kong/kubernetes-ingress-controller/version.RELEASE=0.3.0 -X github.com/kong/kubernetes-ingress-controller/version.COMMIT=git-020ae33 -X github.com/kong/kubernetes-ingress-controller/version.REPO=http://gitlab.puhuitech.cn/infrastructure/kong-ingress-controller.git" -gcflags=-trimpath=/Users/lijiao/Work-Finup/Bin/gopath/src/github.com/Kong/kubernetes-ingress-controller -asmflags=-trimpath=/Users/lijiao/Work-Finup/Bin/gopath/src/github.com/Kong/kubernetes-ingress-controller \
-o /var/folders/c_/q1wyxzx14l713h58k4hkff180000gp/T/tmp.LKqTFGXr/rootfs/kong-ingress-controller github.com/kong/kubernetes-ingress-controller/cli/ingress-controller
生成的kong-ingress-controller默认是ELF格式的。
make all
生成镜像,通过修改Makefile中变量,来调整镜像名称:
TAG?=0.3.0
REGISTRY?=kong-docker-kubernetes-ingress-controller.bintray.io
GOOS?=linux
DOCKER?=docker
SED_I?=sed -i
GOHOSTOS ?= $(shell go env GOHOSTOS)
...
IMGNAME = kong-ingress-controller
IMAGE = $(REGISTRY)/$(IMGNAME)
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
不记录走读笔记了,可以参考以前的:API网关Kong学习笔记(八):Kong Ingress Controller的实现。
kong-ingress-controller需要访问kubernetes的apiserver,监听kubernetes集群中的资源,如果被部署在kubernetes中,它会自动读取pod中的serviceAccount信息,不需要指定访问凭证。
在kubernetes集群外部运行,用--kubeconfig
指定访问kubernetes集群使用的kubeconfig文件。
--ingress-class
指定要处理ingress类型,该参数的值对应的是ingress中名为kubernetes.io/ingress.class
的annotations。
--election-id
指定Leader选举组,这个参数的目的是防止同一个集群中多套
kong-ingress-controller互相干扰,每套kong-ingress-controller都用不同的–election-id,属于同一套的kong-ingress-controller使用相同的–election-id。
--kong-url
指定对接的kong admin。
--watch-namespace
指定监听的namespace,默认是全部。
--publish-service
指定部署在kubernetes中的kong-proxy服务,kong-ingress-controller会取出这个service的IP,并将其更新到每个ingress的status字段中。
如果service的类型是LoadBalancer
,则取出其中配置的IP,如果是其它类型取出对应的Pod所在的Node的IP。
--publish-status-address
,如果使用了参数,忽略–publish-service,使用这个参数指定的IP。
--update-status
和--update-status-on-shutdown
是ingress状态更新开关,默认都是true,即更改ingress的status。
--default-backend-service
指定kubernetes中的一个服务,用于提供404页面的服务,当uri不存在的时候转发到该服务, 选用服务的第一个node port地址。
--publish-service和--default-backend-service都是指定kubernetes集群中的service,不支持IP。
应该改进一下
--sync-period
和--sync-rate-limit
限制刷新频率、刷新速率。
另外还有一些日志参数,这里不列出了。
–update-status的IP获取过程:
// internal/ingress/status/status.go: 257
func (s *statusSync) runningAddresses() ([]string, error) {
addrs := []string{}
if s.PublishStatusAddress != "" {
addrs = append(addrs, s.PublishStatusAddress)
return addrs, nil
}
ns, name, _ := k8s.ParseNameNS(s.PublishService)
svc, err := s.Client.CoreV1().Services(ns).Get(name, metav1.GetOptions{})
if err != nil {
return nil, err
}
switch svc.Spec.Type {
case apiv1.ServiceTypeLoadBalancer:
for _, ip := range svc.Status.LoadBalancer.Ingress {
if ip.IP == "" {
addrs = append(addrs, ip.Hostname)
} else {
addrs = append(addrs, ip.IP)
}
}
addrs = append(addrs, svc.Spec.ExternalIPs...)
return addrs, nil
default:
pods, err := s.Client.CoreV1().Pods(s.pod.Namespace).List(metav1.ListOptions{
LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
})
if err != nil {
return nil, err
}
for _, pod := range pods.Items {
// only Running pods are valid
if pod.Status.Phase != apiv1.PodRunning {
continue
}
name := k8s.GetNodeIPOrName(s.Client, pod.Spec.NodeName)
if !sliceutils.StringInSlice(name, addrs) {
addrs = append(addrs, name)
}
}
return addrs, nil
}
}
--publish-status-address=10.10.64.58
指定状态地址为10.10.64.58后,ingress的地址被设置为10.10.64.58:
$ ./kubectl.sh -n demo-echo get ing
NAME HOSTS ADDRESS PORTS AGE
ingress-echo echo.com 10.10.64.58 80 8d
status:
loadBalancer:
ingress:
- ip: 10.10.64.58
否则获取的是--publish-service=kong/kong-proxy
的pod所在node的IP:
$ ./kubectl.sh -n demo-echo get ing -o wide
NAME HOSTS ADDRESS PORTS AGE
ingress-echo echo.com 10.10.173.203 80 8d
--update-status=false
,不更新ingress的status。(现在kong ingress controller的实现有bug,如果设置为false,kong-ingress-controller启动失败 2019-03-22 10:50:33)
kong ingress controller支持的annotations, 这些annotations都是在ingress中设置。
ingress的类型,与参数--ingress-class
对应:
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "gce"
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "kong"
为ingress设置插件,插件是同一个namespace中的局部KongPlugin,或者任意namespace中的全局KongPlugin:
metadata:
name: foo
annotations:
plugins.konghq.com: high-rate-limit, docs-site-cors
为ingress设置KongIngress,默认是同一个namespace中与ingress同名的KongIngress。
kong ingress controller可以识别4个CRD,分别是KongPluign、KongIngress、KongConsumer、KongCredential。docs/custom-resources.md里有很详细的介绍,不复制了。