自定義Gateway Controller其實(shí)應(yīng)該是一個(gè)很常見(jiàn)的需求,但在網(wǎng)上缺很難找到可以step by step完成的例子。StackOverflow的這個(gè)回答給出了很好的思路,通過(guò)helm template生成yaml,在此基礎(chǔ)上微調(diào),然后使用kubectl apply創(chuàng)建。
基于helm默認(rèn)安裝選項(xiàng)生成的gateway controller,包含以下內(nèi)容:
- 創(chuàng)建一個(gè)有讀取secret權(quán)限的ServiceAccount。
- 以#1創(chuàng)建的account運(yùn)行一個(gè)Pod,里面包含一個(gè)以router方式(而不是sidecar)運(yùn)行的Envoy。
- 創(chuàng)建一個(gè)LoadBalancer類(lèi)型的Service,把#2創(chuàng)建的Pod向外暴露。
- 為#3創(chuàng)建Deploy和Scale相關(guān)的策略。
需要注意的地方有:
- Deployment的template需要關(guān)閉sidecar的自動(dòng)注入。
apiVersion: apps/v1
kind: Deployment
spec:
template:
annotations:
sidecar.istio.io/inject: "false"
- 如果gateway controller不是創(chuàng)建在istio-system namespace下,istio-proxy的啟動(dòng)參數(shù),zipkin和istio-pilot后面要加上.istio-system。
args:
- --zipkinAddress
- zipkin.istio-system:9411
- --discoveryAddress
- istio-pilot.istio-system:15010
- 本例并沒(méi)有打開(kāi)tls,如果需要,要注意調(diào)整需要掛載的secret的名字:
volumes:
- name: istio-certs
secret:
secretName: istio.istio-ingressgateway-service-account
- name: ingressgateway-certs
secret:
secretName: "istio-ingressgateway-certs"
- name: ingressgateway-ca-certs
secret:
secretName: "istio-ingressgateway-ca-certs"
下面貼出生成的yaml文件,以供參考。
# RABC
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-ingressgateway-service-account
namespace: default
labels:
app: my-ingressgateway
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-ingressgateway-sds
namespace: default
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-ingressgateway-sds
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: my-ingressgateway-sds
subjects:
- kind: ServiceAccount
name: my-ingressgateway-service-account
# Service
---
apiVersion: v1
kind: Service
metadata:
name: my-ingressgateway
namespace: default
labels:
app: my-ingressgateway
istio: my-ingressgateway
spec:
type: LoadBalancer
selector:
app: my-ingressgateway
istio: my-ingressgateway
ports:
-
name: http2
port: 80
targetPort: 80
# Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-ingressgateway
namespace: default
labels:
app: my-ingressgateway
istio: my-ingressgateway
spec:
selector:
matchLabels:
app: my-ingressgateway
istio: my-ingressgateway
template:
metadata:
labels:
app: my-ingressgateway
istio: my-ingressgateway
annotations:
sidecar.istio.io/inject: "false"
spec:
serviceAccountName: my-ingressgateway-service-account
containers:
- name: istio-proxy
image: "docker.io/istio/proxyv2:1.2.0"
imagePullPolicy: IfNotPresent
ports:
# healthcheck
- containerPort: 15020
# web
- containerPort: 80
- containerPort: 443
# This port is used for testdata.
- containerPort: 31400
args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.cluster.local
- --log_output_level=default:info
- --drainDuration
- '45s'
- --parentShutdownDuration
- '1m0s'
- --connectTimeout
- '10s'
- --serviceCluster
- my-ingressgateway
- --zipkinAddress
- zipkin.istio-system:9411
- --proxyAdminPort
- "15000"
- --statusPort
- "15020"
- --controlPlaneAuthPolicy
- NONE
- --discoveryAddress
- istio-pilot.istio-system:15010
readinessProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15020
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- 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: HOST_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
- name: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: ISTIO_META_CONFIG_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: ISTIO_META_ROUTER_MODE
value: sni-dnat
volumeMounts:
- name: istio-certs
mountPath: /etc/certs
readOnly: true
- name: ingressgateway-certs
mountPath: "/etc/istio/ingressgateway-certs"
readOnly: true
- name: ingressgateway-ca-certs
mountPath: "/etc/istio/ingressgateway-ca-certs"
readOnly: true
volumes:
- name: istio-certs
secret:
secretName: istio.istio-ingressgateway-service-account
optional: true
- name: ingressgateway-certs
secret:
secretName: "istio-ingressgateway-certs"
optional: true
- name: ingressgateway-ca-certs
secret:
secretName: "istio-ingressgateway-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
# Deploy & Scale Policy
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: my-ingressgateway
namespace: default
labels:
app: my-ingressgateway
istio: my-ingressgateway
spec:
maxReplicas: 3
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-ingressgateway
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 80
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: my-ingressgateway
namespace: default
labels:
app: my-ingressgateway
istio: my-ingressgateway
spec:
minAvailable: 1
selector:
matchLabels:
app: my-ingressgateway
istio: my-ingressgateway