《OpenShift 4.x HOL教程汇总》
说明:本文已经在OpenShift 4.6环境中验证
Ingress和Route
IngressOperator和IngressController
在OpenShift 4中通过Ingress Operator(名为ingress的clusteroperator)供应了Kubernetes的Ingress Controller对象(缺省名为default的ingresscontroller实现route功能)并维护其生命周期,如果该default的ingresscontroller被删掉,Ingress Operator会自动重建新的ingresscontroller实例对象。OpenShift的Ingress Operator可以供应一个或多个基于HAProxy的Ingress Controller来实现外部入栈请求的流量路由。
OpenShift Route和Kubernetes Ingress
Kubernetes缺省的Igress和OpenShift实现的Route功能区别如下:
Ingress Operator操作
查看缺省名为ingress的clusteroperator
$ oc get clusteroperators ingress
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE
ingress 4.14.0 True False False 21d
注意:由于ClusterOperator属于OpenShift集群范围,所以ingress对象不属于任一个Project或NameSpace。
查看Ingress Operator的日志
$ oc logs deployments/ingress-operator -n openshift-ingress-operator -c ingress-operator
Ingress Controller操作
注意:每个IngressController对象实例会对应一个Route(运行在一个或多个pod中),其中名为default的IngressController对象实例是用来实现缺省Route的。
查看名为default的IngressController对象实例
- 查看IngressController的实例对象,并记录名为default实例对象的域名。
$ oc get ingresscontroller -n openshift-ingress-operator
NAME AGE
default 21d
$ SUB_DOMAIN=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')
- 查看名为default实例对象的详细信息,注意:“Replicas: 2”是和workder节点数一致。
$ oc describe ingresscontroller/default -n openshift-ingress-operator
Name: default
Namespace: openshift-ingress-operator
Labels: <none>
Annotations: <none>
API Version: operator.openshift.io/v1
Kind: IngressController
Metadata:
Finalizers:
ingresscontroller.operator.openshift.io/finalizer-ingresscontroller
Generation: 2
Resource Version: 24859
Spec:
Replicas: 2
Status:
Available Replicas: 2
Domain: apps.cluster-beijing-f162.beijing-f162.example.opentlc.com
Endpoint Publishing Strategy:
Type: HostNetwork
Selector: ingresscontroller.operator.openshift.io/deployment-ingresscontroller=default
查看运行Route的部署情况
默认有两个缺省的Route实例;它们应该在两个 worker 节点上运行。
$ oc get deployment -n openshift-ingress
NAME READY UP-TO-DATE AVAILABLE AGE
router-default 2/2 2 2 5d22h
查看名为default的IngressController对象实例的运行日志
- 修改openshift-ingress-operator中名为default的IngressController实例,添加基于sidecar类型的日志。注意:如果日志量比较大,可以使用例如Syslog接收处理日志。
$ oc patch ingresscontroller default --patch '{"spec":{"logging": {"access":{"destination":{"type":"Container"}}}}}' --type=merge -n openshift-ingress-operator
ingresscontroller.operator.openshift.io/default patched
- 查看更新后的配置。
$ oc get ingresscontroller default -n openshift-ingress-operator -ojson| jq '.spec.logging'
{
"access": {
"destination": {
"type": "Container"
}
}
}
- 查看IngressController的日志。注意:也可以直接访问对应的Pod查看日志。
$ oc logs deployment/router-default -n openshift-ingress -c logs -f
Found 2 pods, using pod/router-default-6b57f5d5c8-9rp8d
2020-07-17T01:54:29.871256+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[47]: 127.0.0.1:59046 [17/Jul/2020:01:54:29.870] public openshift_default/<NOSRV> 0/-1/-1/-1/0 503 3288 - - SC-- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
2020-07-17T01:54:40.663324+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy public started.
2020-07-17T01:54:40.663339+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy public_ssl started.
2020-07-17T01:54:40.663343+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy be_sni started.
2020-07-17T01:54:40.663352+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy fe_sni started.
2020-07-17T01:54:40.663355+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy be_no_sni started.
2020-07-17T01:54:40.663366+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy fe_no_sni started.
2020-07-17T01:54:40.663371+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy openshift_default started.
2020-07-17T01:54:40.663375+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy be_http:gogs:gogs started.
2020-07-17T01:54:40.663379+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy be_edge_http:jenkins:jenkins started.
2020-07-17T01:54:40.663382+00:00 router-default-6b57f5d5c8-9rp8d router-default-6b57f5d5c8-9rp8d haproxy[58]: Proxy be_edge_http:knative-serving-ingress:route-bfd14a19-cda8-44d8-b2cf-a6cf77d135c2-306165346332 started.
。。。
扩展名为default的IngressController对象实例数
$ oc patch ingresscontroller default --patch '{"spec":{"replicas": 3}}' --type=merge -n openshift-ingress-operator
ingresscontroller.operator.openshift.io/default patched
注意:由于运行名为default的IngressController的Pod配置了亲和性,因此如果节点数量不够3个,在Event中可能提示以下内容:
0/5 nodes are available: 2 node(s) didn’t match pod affinity/anti-affinity, 2 node(s) didn’t satisfy existing pods anti-affinity rules, 3 node(s) didn’t match node selector.
查看运行缺省Route的项目资源
其中Pod中运行了基于HA-Proxy的缺省Route功能。
$ oc get all -n openshift-ingress
NAME READY STATUS RESTARTS AGE
pod/router-default-5778db665b-2cxcm 2/2 Running 0 10m
pod/router-default-5778db665b-h7vsz 2/2 Running 0 12m
pod/router-default-5778db665b-s5rqh 2/2 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/router-default LoadBalancer 172.30.59.123 a590b350b2cb643e09d434c08d201828-2115003386.ap-southeast-1.elb.amazonaws.com 80:30653/TCP,443:31381/TCP 2d
service/router-internal-default ClusterIP 172.30.72.121 <none> 80/TCP,443/TCP,1936/TCP 2d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/router-default 3/3 3 3 2d
NAME DESIRED CURRENT READY AGE
replicaset.apps/router-default-565d6899d6 0 0 0 33h
replicaset.apps/router-default-5778db665b 3 3 3 12m
replicaset.apps/router-default-59c499f555 0 0 0 47h
replicaset.apps/router-default-6d9cf5fb54 0 0 0 2d
设置应用Route的网络参数
通过设置 App Route(以 myroute 为例)的 annotation 可以修改其对应的网络参数。
设置Route超时
以下将超时时间设为2秒。OpenShift支持的时间单位是微秒 (us)、毫秒 (ms)、秒钟 (s)、分钟 (m)、小时 (h)、或天 (d)。
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
设置负载均衡算法
OpenShift 支持的负载均衡算法包括 source、roundrobin 和 leastconn,缺省是 leastconn。
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/balance=roundrobin
设置Pod最大并发连接数
设置一个 Pod 最多可以同时有的连接数量。
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/pod-concurrent-connections=10
设置DDoS攻击保护
设置以下参数可以保护Route受到DDoS攻击。
# 是否允许保护
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/rate-limit-connections=true
## 允许来自一个IP的客户端同时能够打开的TCP连接
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/rate-limit-connections.concurrent-tcp=5
# 允许来自一个IP的客户端每秒可以建立的TCP连接数
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/rate-limit-connections.rate-tcp=5
# 允许来自一个IP的客户端每秒可以建立的HTTP连接数
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/rate-limit-connections.rate-http=5
设置访问白名单
只有白名单内的客户端才可访问 Route。白名单可以是一个或多个IP,还可以是 CIDR 形式的地址段。
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/ip_whitelist=192.168.1.0/24
Shard Route
为什么使用Shard Route
作为访问流量进入OpenShift 集群的主要机制,对 于Ingress Controller 或 Route,可以使用 Shard 提供以下更加灵活的功能:
- 通过使用多个 Ingress Controller 或 Route 加快请求响应速度。
- 让特定 Route 具有与其它 Route 不同的可靠性保证。
- 允许某些 Ingress Controllers定义不同的策略。
- 只允许特定的 Route 使用某些特定功能。
- 在不同的地址上公开不同的 Route,让内部和外部用户访问不同的 Route。
实现 Shard Route
- 根据以下内容创建名为 myshard 的 IngressController。其中 “myshard-${SUB_DOMAIN}” 是该 shard route 使用的新 subdomain 名称。
$ oc apply -f - << EOF
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
name: myshard
namespace: openshift-ingress-operator
spec:
domain: myshard-${SUB_DOMAIN}
endpointPublishingStrategy:
type: LoadBalancerService
loadBalancer:
scope: Internal
nodePlacement:
nodeSelector:
matchLabels:
node-role.kubernetes.io/worker: ""
routeSelector:
matchLabels:
type: myshard
EOF
- 查看 IngressController 对象的实例,确认多了 “myshard”。
$ oc get IngressController -n openshift-ingress-operator
NAME AGE
default 2d
myshard 27s
- 查看运行 Route 的部署情况。可以看出 OpenShift 会为每个 IngressController 实例对应一个 Deployment。
$ oc get deployment -n openshift-ingress
NAME READY UP-TO-DATE AVAILABLE AGE
router-default 3/3 3 3 2d
router-myshard 2/2 2 2 33s
- 部署应用,然后生成 route,注意需要指定其 hostname 和 lable(type=myshard)。
$ oc new-project hello-openshift
$ oc new-app openshift/hello-openshift -n hello-openshift
$ oc expose svc hello-openshift --hostname=hello-openshift-hello-openshift.myshard-${SUB_DOMAIN}
$ oc label route hello-openshift type=myshard
- 确认此时 hello-openshift-myshard 已可以使用名为 myshard 的 Router。
$ oc describe route hello-openshift-myshard
Name: hello-openshift-myshard
Namespace: hello-openshift
Created: 2 minutes ago
Labels: app=hello-openshift
app.kubernetes.io/component=hello-openshift
app.kubernetes.io/instance=hello-openshift
type=myshard
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"route.openshift.io/v1","kind":"Route","metadata":{"annotations":{},"labels":{"app":"hello-openshift","app.kubernetes.io/component":"hello-openshift","app.kubernetes.io/instance":"hello-openshift","type":"myshard"},"name":"hello-openshift-myshard","namespace":"hello-openshift"},"spec":{"host":"hello-openshift-hello-openshift.myshard-apps.cluster-j6cg9.j6cg9.sandbox1011.opentlc.com","port":{"targetPort":"8080-tcp"},"to":{"kind":"Service","name":"hello-openshift"}}}
Requested Host: hello-openshift-hello-openshift.myshard-apps.cluster-j6cg9.j6cg9.sandbox1011.opentlc.com
exposed on router default (host router-default.apps.cluster-j6cg9.j6cg9.sandbox1011.opentlc.com) 2 minutes ago
exposed on router myshard (host router-myshard.myshard-apps.cluster-j6cg9.j6cg9.sandbox1011.opentlc.com) 2 minutes ago
Path: <none>
TLS Termination: <none>
Insecure Policy: <none>
Endpoint Port: 8080-tcp
Service: hello-openshift
Weight: 100 (100%)
Endpoints: 10.128.0.100:8080
- 访问 hello-openshift 的 route 地址,确认可以访问。
$ curl hello-openshift-hello-openshift.myshard-${SUB_DOMAIN}
Hello OpenShift!
参考
https://docs.openshift.com/container-platform/4.13/networking/ingress-sharding.html
https://access.redhat.com/solutions/3880621
https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html