部署自定义HAProxy Router

苏晓林 [email protected]                    openshift version:3.6

概览

默认的HAProxy Router已经能够满足绝大部分的用户需求。但是默认的HAProxy Router并不支持所有的HAProxy功能,一些用户可能需要用到这些功能。

有的用户可能需要用到一些application back-ends的新特性,或者修改一些当前操作。router plug-in能通过定制的方式满足所有这些需求。

Router pod使用golang template来创建HAProxy的配置文件。当处理template时,Router需要访问OpenShift Origin的信息,包括Router的部署配置,允许的routes集合和其它一些帮助功能。

当Router pod启动和每次reload时,都会创建一个HAProxy配置文件,然后启动HAProxy。HAProxy configuration manual 给出HAProxy的所有特性,以及如何构建一个有效的配置文件。

可以通过将configMap添加到template来部署Router pod。通过这种方法部署时,需要修改Router的部署配置,将configMap以volume的方式挂载到Router pod中。并且将环境变量TEMPLATE_FILE配置为template文件在Router pod中的全路径。

或者,你也可以构建一个自定义的Router镜像,通过它来部署你的Routers。构建Routers的镜像可以不同。通过修改haproxy-template.config文件,然后重新构建Router的镜像。新的镜像会被上传到集群的镜像仓库,并且Router的部署配置中,image:字段更新为新的镜像名称。当集群有更改时,需要重新构建镜像并上传。

无论哪种方式,router pod的部署都是从template文件开始。

获得Router的template

HAProxy的template非常巨大且复杂。通常通过修改已有template的方式会更加方便和简单。可以通过以下命令在一个运行router的master节点上获得一个新的haproxy-config.template

# oc get po
NAME                       READY     STATUS    RESTARTS   AGE
router-2-40fc3             1/1       Running   0          11d
# oc rsh router-2-40fc3 cat haproxy-config.template > haproxy-config.template
# oc rsh router-2-40fc3 cat haproxy.config > haproxy.config

或者,你可以登录到运行Router的节点,执行以下命令

# docker run --rm --interactive=true --tty --entrypoint=cat \
    openshift/origin-haproxy-router haproxy-config.template

将执行结果保存,作为基础配置文件,然后修改得到你的自定义配置,并最终生成配置文件haproxy.config

修改Router的template

Background

HAProxy的template是以golang template为基础,能够解析部署时配置的环境变量,下面介绍的所有配置信息以及函数。

HAProxy的配置文件通过template生成,在生成过程中,所有{{" something "}}格式的内容将处理解析后写入到配置文件中,其它格式的内容将直接拷贝。

模版提供的功能

define关键字定义了template处理后生成的配置文件位置

{{define "/var/lib/haproxy/conf/haproxy.config"}}pipeline{{end}}

表1,template处理函数

函数
endpointsForAlias(alias ServiceAliasConfig, svc ServiceUnit) []Endpoint 返回可用的endpoints列表.
env(variable, default string) string 尝试获得pod的环境变量,如果获得失败或为空,返回默认值default.
matchPattern(pattern, s string) bool 正则匹配,第一个参数为正则表达式,第二个为要匹配的字符串,返回结果为布尔类型.
isInteger(s string) bool 判断参数变量是否为整型.
matchValues(s string, allowedValues …​string) bool 匹配字符串s,是否在字符串列表allowedValues中.
genSubdomainWildcardRegexp(hostname, path string, exactPath bool) string Generates a regular expression matching the subdomain for hosts (and paths) with a wildcard policy.
generateRouteRegexp(hostname, path string, wildcard bool) string Generates a regular expression matching the route hosts (and paths). The first argument is the host name, the second is the path, and the third is a wildcard Boolean.
genCertificateHostName(hostname string, wildcard bool) string Generates host name to use for serving/matching certificates. First argument is the host name and the second is the wildcard Boolean.

Router提供的参数

本节介绍Router可用于OpenShift Origin的参数,这些参数是HAProxy router plug-in提供的,通过.Fieldname访问。

表2,Router配置参数

字段 类型 描述
WorkingDir string 写文件的目录,默认目录:/var/lib/containers/router
State map[string](ServiceAliasConfig) The routes.
ServiceUnits map[string]ServiceUnit The service lookup.
DefaultCertificate string 以pem格式指定默认证书的完整路径名称。
PeerEndpoints `[]Endpoint Peers.
StatsUser string User name to expose stats with (if the template supports it).
StatsPassword string Password to expose stats with (if the template supports it).
StatsPort int Port to expose stats with (if the template supports it).
BindPorts bool Whether the router should bind the default ports.
表3,Router ServiceAliasConfig
字段 类型 描述
Name string 用户指定的Route的名称.
Namespace string The namespace of the route.
Host string The host name. For example,www.example.com.
Path string Optional path. For example,www.example.com/myservicewheremyserviceis the path.
TLSTermination routeapi.TLSTerminationType back-end的终止策略; drives the mapping files and router configuration.
Certificates map[string]Certificate Certificates used for securing this back-end. Keyed by the certificate ID.
Status ServiceAliasConfigStatus Indicates the status of configuration that needs to be persisted.
PreferPort string Indicates the port the user wants to expose. If empty, a port will be selected for the service.
InsecureEdgeTerminationPolicy routeapi.InsecureEdgeTerminationPolicyType Indicates desired behavior for insecure connections to an edge-terminated route:none(ordisable),allow, orredirect.
RoutingKeyName string Hash of the route + namespace name used to obscure the cookie ID.
IsWildcard bool Indicates this service unit needing wildcard support.
Annotations map[string]string Annotations attached to this route.
ServiceUnitNames map[string]int32 Collection of services that support this route, keyed by service name and valued on the weight attached to it with respect to other entries in the map.
ActiveServiceUnits int Count of theServiceUnitNameswith a non-zero weight.

ServiceAliasConfig是service的route配置. 由host + path确定唯一性. 默认template通过{{range $cfgIdx, $cfg := .State }} 遍历所有routes.

表4,ServiceUnit
字段 类型 描述
Name string Name corresponds to a service name + namespace. Uniquely identifies theServiceUnit.
EndpointTable []Endpoint Endpoints that back the service. This translates into a final back-end implementation for routers.

ServiceUnit是service的封装,包括service后端的endpoints和指向service的routes.

表5,Router Endpoint
Field Type
ID string
IP string
Port string
TargetName string
PortName string
IdHash string
NoHealthCheck bool

Endpointis an internal representation of a Kubernetes endpoint.

表6,Router Certificate, ServiceAliasConfigStatus
Field Type Description
Certificate string Represents a public/private key pair. It is identified by an ID, which will become the file name. A CA certificate will not have aPrivateKeyset.
ServiceAliasConfigStatus string Indicates that the necessary files for this configuration have been persisted to disk. Valid values: "saved", "".
表7,Router Certificate Type
Field Type Description
ID string
Contents string The certificate.
PrivateKey string The private key.
表8,Router TLSTerminationType
Field Type Description
TLSTerminationType string Dictates where the secure communication will stop.
InsecureEdgeTerminationPolicyType string Indicates the desired behavior for insecure connections to a route. While each router may make its own decisions on which ports to expose, this is normally port 80.

TLSTerminationTypeandInsecureEdgeTerminationPolicyTypedictate where the secure communication will stop.

表9,Router TLSTerminationType Values
Constant Value Meaning
TLSTerminationEdge edge Terminate encryption at the edge router.
TLSTerminationPassthrough passthrough Terminate encryption at the destination, the destination is responsible for decrypting traffic.
TLSTerminationReencrypt reencrypt Terminate encryption at the edge router and re-encrypt it with a new certificate supplied by the destination.
表10,Router InsecureEdgeTerminationPolicyType Values
Type Meaning
Allow Traffic is sent to the server on the insecure port (default).
Disable No traffic is allowed on the insecure port.
Redirect Clients are redirected to the secure port.

None ("") is the same asDisable.

Annotations

每个route都能够添加annotations,每个annotation有name和value组成。

apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/timeout: 5500ms
[...]

name可以为任意值,当不能与已存在的name冲突。value为任意字符串。例如aa bb cc。template使用{{index}}的方式获得annotation的值。例:

{{$balanceAlgo := index $cfg.Annotations "haproxy.router.openshift.io/balance"}}

下例中展示了如何进行客户端互相认证

{{ with $cnList := index $cfg.Annotations "whiteListCertCommonName" }}
  {{   if ne $cnList "" }}
    acl test ssl_c_s_dn(CN) -m str {{ $cnList }}
    http-request deny if !test
  {{   end }}
{{ end }}

然后,使用以下命令将CNs加入白名单。

$ oc annotate route <route-name> --overwrite whiteListCertCommonName="CN1 CN2 CN3"

环境变量

template能够使用router pod中的所有环境变量。环境变量可以通过deployment configuration进行设置。

在使用时通过函数env获得环境变量的值:

{{env "ROUTER_MAX_CONNECTIONS" "20000"}}

用例

下面是一个简单的HAProxy template文件

由以下内容开头:

{{/*
  Here is a small example of how to work with templates
  taken from the HAProxy template file.
*/}}

template可以创建任意数量的输出文件。文件名称为define的参数。

{{ define "/var/lib/haproxy/conf/haproxy.config" }}
global
{{ end }}

上面的操作会将global拷贝到文件/var/lib/haproxy/conf/haproxy.config中,然后关闭该文件。

通过环境变量设置日志

{{ with (env "ROUTER_SYSLOG_ADDRESS" "") }}
  log {{.}} {{env "ROUTER_LOG_FACILITY" "local1"}} {{env "ROUTER_LOG_LEVEL" "warning"}}
{{ end }}

总结

上面其实主要介绍了template的一些配置。所谓的自定义安装HAProxy,其实指的是通过修改template来自定义HAProxy的配置。

实现方法:

1.是构建一个configMap,将修改过的template关联到该configMap上。当再次部署router的时候,通过configMap将自定义的template应用到新的HAProxy上。

2.是修改template后,重新构建一个image,在部署router的时候,指定该image。

详细配置查看原文连接:https://docs.openshift.org/latest/install\_config/router/customized\_haproxy\_router.html

results matching ""

    No results matching ""