如何创建自定义 istio 入口网关控制器?
How to create custom istio ingress gateway controller?
我们的 GKE 集群共享给公司的多个团队。每个团队可以有不同的 public 域(因此希望有不同的 CA 证书设置和不同的入口网关控制器)。如何在 Istio 中做到这一点? Istio 网站上的所有 tutorial/introduction 文章都使用共享入口网关。请参阅 istio-1.0.0 安装的示例共享入口网关:
https://istio.io/docs/tasks/traffic-management/secure-ingress/
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
我猜的,我还没试过:
使用不同的标签创建多个 istio-ingressgateway 部署,例如:istio: ingressgateway1, istio: ingressgateway2, ..., 和不同的 tls 密钥。
创建多个网关以使用不同的 istio-ingressgateways。
创建多个虚拟服务以使用不同的网关。
好的,看了helm安装Istio的代码,找到了答案。所以,基本上 istio 有一个官方的方式(但没有真正记录在他们的 readme.md 文件中)来添加额外的网关(入口和出口网关)。我知道是因为我在他们的 github 存储库中找到了这个 yaml file 并阅读了评论(还查看了规范及其逻辑的 gateway
图表模板代码)。
所以,我解决了这个问题,例如,定义这个 values-custom-gateway.yaml 文件:
# Gateways Configuration
# By default (if enabled) a pair of Ingress and Egress Gateways will be created for the mesh.
# You can add more gateways in addition to the defaults but make sure those are uniquely named
# and that NodePorts are not conflicting.
# Disable specifc gateway by setting the `enabled` to false.
#
gateways:
enabled: true
agung-ingressgateway:
namespace: agung-ns
enabled: true
labels:
app: agung-istio-ingressgateway
istio: agung-ingressgateway
replicaCount: 1
autoscaleMin: 1
autoscaleMax: 2
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
#requests:
# cpu: 1800m
# memory: 256Mi
loadBalancerIP: ""
serviceAnnotations: {}
type: LoadBalancer #change to NodePort, ClusterIP or LoadBalancer if need be
ports:
## You can add custom gateway ports
- port: 80
targetPort: 80
name: http2
# nodePort: 31380
- port: 443
name: https
# nodePort: 31390
- port: 31400
name: tcp
secretVolumes:
- name: ingressgateway-certs
secretName: istio-ingressgateway-certs
mountPath: /etc/istio/ingressgateway-certs
- name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
mountPath: /etc/istio/ingressgateway-ca-certs
如果你看一下上面的 yaml 文件,我指定了 namespace
而不是 istio-system
ns。在这种情况下,我们可以有一种方法来自定义我们的自定义网关使用的 TLS 和 ca 证书。
此外,agung-ingressgateway
作为自定义网关控制器规范的持有者被用作网关控制器的名称。
然后,我只是通过 helm upgrade --install
安装 istio,这样 helm 就可以通过额外的网关智能升级 istio。
helm upgrade my-istio-release-name <istio-chart-folder> --install
升级成功后,我可以为我的 Gateway
:
指定自定义选择器
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: agung-gateway
namespace: agung-ns
spec:
selector:
app: agung-istio-ingressgateway # use custom gateway
# istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
hosts:
- "*"
其实很简单。 Istio 的入口只是 "Load Balancer" 类型的常规 Kubernetes 服务。所以,如果你想创建额外的 IngresGateway,你可以只应用你的服务(你可以放置任何你想要的端口):
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway-custom
namespace: istio-system
annotations:
labels:
chart: gateways-1.0.5
release: istio
heritage: Tiller
app: istio-ingressgateway
istio: ingressgateway
spec:
type: LoadBalancer
selector:
app: istio-ingressgateway
istio: ingressgateway
ports:
-
name: http2
nodePort: 31381
port: 80
targetPort: 80
-
name: https
nodePort: 31391
port: 443
targetPort: 555
-
name: tcp
nodePort: 31401
port: 31400
-
name: tcp-pilot-grpc-tls
port: 15011
targetPort: 15011
-
name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
-
name: tcp-dns-tls
port: 853
targetPort: 853
-
name: http2-prometheus
port: 15030
targetPort: 15030
-
name: http2-grafana
port: 15031
targetPort: 15031
---
考虑到你在名为 "customingress.yaml" 的文件中有这个,然后你使用命令应用它:
kubectl apply -f customingress.yaml
我尝试了这个并且成功了:
---
# Source: istio/charts/gateways/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: beta-ingressgateway-service-account
namespace: beta
labels:
app: ingressgateway-beta
---
---
# Source: istio/charts/gateways/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
labels:
app: gateways
name: ingressgateway-beta
rules:
- apiGroups: ["extensions"]
resources: ["thirdpartyresources", "virtualservices", "destinationrules", "gateways"]
verbs: ["get", "watch", "list", "update"]
---
---
# Source: istio/charts/gateways/templates/clusterrolebindings.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ingressgateway-beta
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingressgateway-beta
subjects:
- kind: ServiceAccount
name: beta-ingressgateway-service-account
namespace: beta
---
---
# Source: istio/charts/gateways/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: ingressgateway-beta
namespace: beta
annotations:
labels:
istio: ingressgateway-beta
spec:
type: LoadBalancer
selector:
istio: ingressgateway-beta
ports:
-
name: http
port: 80
targetPort: 80
-
name: https
port: 443
targetPort: 443
---
---
# Source: istio/charts/gateways/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ingressgateway-beta
namespace: beta
labels:
istio: ingressgateway-beta
spec:
replicas: 1
template:
metadata:
labels:
istio: ingressgateway-beta
annotations:
sidecar.istio.io/inject: "false"
scheduler.alpha.kubernetes.io/critical-pod: ""
spec:
serviceAccountName: beta-ingressgateway-service-account
tolerations:
- key: "env"
operator: "Equal"
value: "beta"
effect: "NoSchedule"
nodeSelector:
env: beta
containers:
- name: istio-proxy
image: "ISTIO_PROXY_IMAGE"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
args:
- proxy
- router
- -v
- "2"
- --discoveryRefreshDelay
- '1s' #discoveryRefreshDelay
- --drainDuration
- '45s' #drainDuration
- --parentShutdownDuration
- '1m0s' #parentShutdownDuration
- --connectTimeout
- '10s' #connectTimeout
- --serviceCluster
- ingressgateway-beta
- --zipkinAddress
- zipkin.istio-system:9411
- --proxyAdminPort
- "15000"
- --controlPlaneAuthPolicy
- NONE
- --discoveryAddress
- istio-pilot.istio-system:8080
resources:
requests:
cpu: 10m
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- name: istio-certs
mountPath: /etc/certs
readOnly: true
- name: ingressgateway-beta-certs
mountPath: "/etc/istio/ingressgateway-beta-certs"
readOnly: true
- name: ingressgateway-beta-ca-certs
mountPath: "/etc/istio/ingressgateway-beta-ca-certs"
readOnly: true
volumes:
- name: istio-certs
secret:
secretName: istio.beta-ingressgateway-service-account
optional: true
- name: ingressgateway-beta-certs
secret:
secretName: "istio-ingressgateway-beta-certs"
optional: true
- name: ingressgateway-beta-ca-certs
secret:
secretName: "istio-ingressgateway-beta-ca-certs"
optional: true
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
- ppc64le
- s390x
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- ppc64le
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- s390x
---
---
# Source: istio/charts/gateways/templates/autoscale.yaml
# Source: istio/charts/gateways/templates/autoscale.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: ingressgateway-beta
namespace: beta
spec:
maxReplicas: 5
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1beta1
kind: Deployment
name: ingressgateway-beta
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 80
---
记得替换ISTIO_PROXY_IMAGE
、nodeSelector
和tolerations
这是我在 Istio 1.4 中使用的。
在您自己的命名空间(本例中为 bookinfo)中生成新的 istio-ingressgateway Deployment、Service 和 ServiceAccount
helm template install/kubernetes/helm/istio/ \
--namespace bookinfo \
--set global.istioNamespace=istio-system \
-x charts/gateways/templates/deployment.yaml \
-x charts/gateways/templates/service.yaml \
-x charts/gateways/templates/serviceaccount.yaml \
--set gateways.istio-ingressgateway.enabled=true \
--set gateways.istio-egressgateway.enabled=false \
--set gateways.istio-ingressgateway.labels.app=custom-istio-ingressgateway \
--set gateways.istio-ingressgateway.labels.istio=custom-ingressgateway \
> customingress.yaml
然后,应用生成的文件:
kubectl apply -f customingress.yaml
现在,您可以从您的网关资源中引用它,例如:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: custom-ingressgateway # use the CUSTOM istio controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
您可以通过将其添加到 helm 模板命令来设置自定义服务注释,如下所示:
--set gateways.istio-ingressgateway.serviceAnnotations.'service\.kubernetes\.io/ibm-load-balancer-cloud-provider-ip-type'=private \
我们的 GKE 集群共享给公司的多个团队。每个团队可以有不同的 public 域(因此希望有不同的 CA 证书设置和不同的入口网关控制器)。如何在 Istio 中做到这一点? Istio 网站上的所有 tutorial/introduction 文章都使用共享入口网关。请参阅 istio-1.0.0 安装的示例共享入口网关: https://istio.io/docs/tasks/traffic-management/secure-ingress/
spec:
selector:
istio: ingressgateway # use istio default ingress gateway
我猜的,我还没试过:
使用不同的标签创建多个 istio-ingressgateway 部署,例如:istio: ingressgateway1, istio: ingressgateway2, ..., 和不同的 tls 密钥。
创建多个网关以使用不同的 istio-ingressgateways。
创建多个虚拟服务以使用不同的网关。
好的,看了helm安装Istio的代码,找到了答案。所以,基本上 istio 有一个官方的方式(但没有真正记录在他们的 readme.md 文件中)来添加额外的网关(入口和出口网关)。我知道是因为我在他们的 github 存储库中找到了这个 yaml file 并阅读了评论(还查看了规范及其逻辑的 gateway
图表模板代码)。
所以,我解决了这个问题,例如,定义这个 values-custom-gateway.yaml 文件:
# Gateways Configuration
# By default (if enabled) a pair of Ingress and Egress Gateways will be created for the mesh.
# You can add more gateways in addition to the defaults but make sure those are uniquely named
# and that NodePorts are not conflicting.
# Disable specifc gateway by setting the `enabled` to false.
#
gateways:
enabled: true
agung-ingressgateway:
namespace: agung-ns
enabled: true
labels:
app: agung-istio-ingressgateway
istio: agung-ingressgateway
replicaCount: 1
autoscaleMin: 1
autoscaleMax: 2
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
#requests:
# cpu: 1800m
# memory: 256Mi
loadBalancerIP: ""
serviceAnnotations: {}
type: LoadBalancer #change to NodePort, ClusterIP or LoadBalancer if need be
ports:
## You can add custom gateway ports
- port: 80
targetPort: 80
name: http2
# nodePort: 31380
- port: 443
name: https
# nodePort: 31390
- port: 31400
name: tcp
secretVolumes:
- name: ingressgateway-certs
secretName: istio-ingressgateway-certs
mountPath: /etc/istio/ingressgateway-certs
- name: ingressgateway-ca-certs
secretName: istio-ingressgateway-ca-certs
mountPath: /etc/istio/ingressgateway-ca-certs
如果你看一下上面的 yaml 文件,我指定了 namespace
而不是 istio-system
ns。在这种情况下,我们可以有一种方法来自定义我们的自定义网关使用的 TLS 和 ca 证书。
此外,agung-ingressgateway
作为自定义网关控制器规范的持有者被用作网关控制器的名称。
然后,我只是通过 helm upgrade --install
安装 istio,这样 helm 就可以通过额外的网关智能升级 istio。
helm upgrade my-istio-release-name <istio-chart-folder> --install
升级成功后,我可以为我的 Gateway
:
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: agung-gateway
namespace: agung-ns
spec:
selector:
app: agung-istio-ingressgateway # use custom gateway
# istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
hosts:
- "*"
其实很简单。 Istio 的入口只是 "Load Balancer" 类型的常规 Kubernetes 服务。所以,如果你想创建额外的 IngresGateway,你可以只应用你的服务(你可以放置任何你想要的端口):
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway-custom
namespace: istio-system
annotations:
labels:
chart: gateways-1.0.5
release: istio
heritage: Tiller
app: istio-ingressgateway
istio: ingressgateway
spec:
type: LoadBalancer
selector:
app: istio-ingressgateway
istio: ingressgateway
ports:
-
name: http2
nodePort: 31381
port: 80
targetPort: 80
-
name: https
nodePort: 31391
port: 443
targetPort: 555
-
name: tcp
nodePort: 31401
port: 31400
-
name: tcp-pilot-grpc-tls
port: 15011
targetPort: 15011
-
name: tcp-citadel-grpc-tls
port: 8060
targetPort: 8060
-
name: tcp-dns-tls
port: 853
targetPort: 853
-
name: http2-prometheus
port: 15030
targetPort: 15030
-
name: http2-grafana
port: 15031
targetPort: 15031
---
考虑到你在名为 "customingress.yaml" 的文件中有这个,然后你使用命令应用它:
kubectl apply -f customingress.yaml
我尝试了这个并且成功了:
---
# Source: istio/charts/gateways/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: beta-ingressgateway-service-account
namespace: beta
labels:
app: ingressgateway-beta
---
---
# Source: istio/charts/gateways/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
labels:
app: gateways
name: ingressgateway-beta
rules:
- apiGroups: ["extensions"]
resources: ["thirdpartyresources", "virtualservices", "destinationrules", "gateways"]
verbs: ["get", "watch", "list", "update"]
---
---
# Source: istio/charts/gateways/templates/clusterrolebindings.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: ingressgateway-beta
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingressgateway-beta
subjects:
- kind: ServiceAccount
name: beta-ingressgateway-service-account
namespace: beta
---
---
# Source: istio/charts/gateways/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: ingressgateway-beta
namespace: beta
annotations:
labels:
istio: ingressgateway-beta
spec:
type: LoadBalancer
selector:
istio: ingressgateway-beta
ports:
-
name: http
port: 80
targetPort: 80
-
name: https
port: 443
targetPort: 443
---
---
# Source: istio/charts/gateways/templates/deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ingressgateway-beta
namespace: beta
labels:
istio: ingressgateway-beta
spec:
replicas: 1
template:
metadata:
labels:
istio: ingressgateway-beta
annotations:
sidecar.istio.io/inject: "false"
scheduler.alpha.kubernetes.io/critical-pod: ""
spec:
serviceAccountName: beta-ingressgateway-service-account
tolerations:
- key: "env"
operator: "Equal"
value: "beta"
effect: "NoSchedule"
nodeSelector:
env: beta
containers:
- name: istio-proxy
image: "ISTIO_PROXY_IMAGE"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- containerPort: 443
args:
- proxy
- router
- -v
- "2"
- --discoveryRefreshDelay
- '1s' #discoveryRefreshDelay
- --drainDuration
- '45s' #drainDuration
- --parentShutdownDuration
- '1m0s' #parentShutdownDuration
- --connectTimeout
- '10s' #connectTimeout
- --serviceCluster
- ingressgateway-beta
- --zipkinAddress
- zipkin.istio-system:9411
- --proxyAdminPort
- "15000"
- --controlPlaneAuthPolicy
- NONE
- --discoveryAddress
- istio-pilot.istio-system:8080
resources:
requests:
cpu: 10m
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- name: istio-certs
mountPath: /etc/certs
readOnly: true
- name: ingressgateway-beta-certs
mountPath: "/etc/istio/ingressgateway-beta-certs"
readOnly: true
- name: ingressgateway-beta-ca-certs
mountPath: "/etc/istio/ingressgateway-beta-ca-certs"
readOnly: true
volumes:
- name: istio-certs
secret:
secretName: istio.beta-ingressgateway-service-account
optional: true
- name: ingressgateway-beta-certs
secret:
secretName: "istio-ingressgateway-beta-certs"
optional: true
- name: ingressgateway-beta-ca-certs
secret:
secretName: "istio-ingressgateway-beta-ca-certs"
optional: true
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
- ppc64le
- s390x
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- ppc64le
- weight: 2
preference:
matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- s390x
---
---
# Source: istio/charts/gateways/templates/autoscale.yaml
# Source: istio/charts/gateways/templates/autoscale.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: ingressgateway-beta
namespace: beta
spec:
maxReplicas: 5
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1beta1
kind: Deployment
name: ingressgateway-beta
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 80
---
记得替换ISTIO_PROXY_IMAGE
、nodeSelector
和tolerations
这是我在 Istio 1.4 中使用的。
在您自己的命名空间(本例中为 bookinfo)中生成新的 istio-ingressgateway Deployment、Service 和 ServiceAccount
helm template install/kubernetes/helm/istio/ \
--namespace bookinfo \
--set global.istioNamespace=istio-system \
-x charts/gateways/templates/deployment.yaml \
-x charts/gateways/templates/service.yaml \
-x charts/gateways/templates/serviceaccount.yaml \
--set gateways.istio-ingressgateway.enabled=true \
--set gateways.istio-egressgateway.enabled=false \
--set gateways.istio-ingressgateway.labels.app=custom-istio-ingressgateway \
--set gateways.istio-ingressgateway.labels.istio=custom-ingressgateway \
> customingress.yaml
然后,应用生成的文件:
kubectl apply -f customingress.yaml
现在,您可以从您的网关资源中引用它,例如:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: custom-ingressgateway # use the CUSTOM istio controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
您可以通过将其添加到 helm 模板命令来设置自定义服务注释,如下所示:
--set gateways.istio-ingressgateway.serviceAnnotations.'service\.kubernetes\.io/ibm-load-balancer-cloud-provider-ip-type'=private \