k8s中部署traefik并開啟https支持
k8s中部署traefik并開啟https支持
k8s現(xiàn)在已經(jīng)是容器編排領(lǐng)域的事實標準了,而在我們部署k8s集群時,ingress組件是必不可少的,在k8s領(lǐng)域,做的比較好的ingress組件就是traefik了,原生支持k8s,配置簡單,上手極快,下面我們就來講講如何部署traefik并開啟https支持;
1、生成https證書
如果已有證書則可以跳過此步驟
先創(chuàng)建ca:
openssl genrsa -out ca.key 4096
# 注意這里替換xxx.com為你自己的網(wǎng)址
openssl req -x509 -new -nodes -sha512 -days 36500 \
-subj "/C=CN/ST=Henan/L=Henan/O=Joe/OU=IT/CN=xxx.com" \
-key ca.key \
-out ca.crt
根據(jù)ca簽發(fā)證書:
openssl genrsa -out tls.key 2048
openssl req -new -key tls.key -out tls.csr -days 36500
openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt -days 36500
2、將證書放入k8s的secret
執(zhí)行以下命令:
kubectl create secret generic traefik-tls --from-file=ssl.crt --from-file=ssl.key -n kube-system
3、部署traefik
默認安裝到了kube-system命名空間
要部署traefik,我們只需要在k8s中安裝以下yaml文件即可():
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
namespace: kube-system
data:
traefik.yaml: |-
serversTransport:
insecureSkipVerify: true
api:
insecure: true
dashboard: true
metrics:
prometheus: ""
entryPoints:
# dns端口
dns:
address: ":53/udp"
# 應(yīng)用http端口
web:
address: ":80"
# 設(shè)置forwardedHeaders為insecure,始終信任請求頭中的X-Forwarded-*,也就是無論哪個ip過來的請求,我們都信任其攜帶的X-Forwarded-*請求頭,將其轉(zhuǎn)發(fā)到后端
forwardedHeaders:
insecure: true
transport:
# 設(shè)置優(yōu)雅退出時間
lifeCycle:
requestAcceptGraceTimeout: 10s
graceTimeOut: 10s
respondingTimeouts:
# 讀取請求的超時時間,0表示不會超時
readTimeout: 10s
# 響應(yīng)超時時間,從接受完請求到完全寫出響應(yīng)之間的時間,0表示不會超時
writeTimeout: 300s
# keep-alive最長時間,如果超過該時間仍然沒有數(shù)據(jù)那么連接將會中斷
idleTimeout: 300s
# 應(yīng)用https端口
websecure:
address: ":443"
# 設(shè)置forwardedHeaders為insecure,始終信任請求頭中的X-Forwarded-*,也就是無論哪個ip過來的請求,我們都信任其攜帶的X-Forwarded-*請求頭,將其轉(zhuǎn)發(fā)到后端
forwardedHeaders:
insecure: true
transport:
# 設(shè)置優(yōu)雅退出時間
lifeCycle:
requestAcceptGraceTimeout: 10s
graceTimeOut: 10s
respondingTimeouts:
# 讀取請求的超時時間,0表示不會超時
readTimeout: 10s
# 響應(yīng)超時時間,從接受完請求到完全寫出響應(yīng)之間的時間,0表示不會超時
writeTimeout: 300s
# keep-alive最長時間,如果超過該時間仍然沒有數(shù)據(jù)那么連接將會中斷
idleTimeout: 300s
tls:
# tls選項
options:
default:
minVersion: VersionTLS12
maxVersion: VersionTLS13
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
# 服務(wù)發(fā)現(xiàn),使用kubernetes
providers:
kubernetesCRD: ""
kubernetesingress: ""
# traefik本身的日志配置,日志級別:DEBUG, PANIC, FATAL, ERROR, WARN, and INFO
log:
level: warn
format: json
# 訪問日志配置
accessLog:
filePath: "/traefik/log/access.log"
format: json
# 內(nèi)存中保存的日志行數(shù)buffer,當內(nèi)存中日志行數(shù)超過該buffer值才會寫出到磁盤
bufferingSize: 100
---
# traefik部署先決條件,先部署以下內(nèi)容
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: serverstransports.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: ServersTransport
plural: serverstransports
singular: serverstransport
scope: Namespaced
---
# RBAC權(quán)限控制
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress
subjects:
- kind: ServiceAccount
name: traefik-ingress
namespace: kube-system
---
# serviceAccount定義
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: traefik-ingress
---
# 真正的服務(wù)安裝
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik-ingress
namespace: kube-system
labels:
app: traefik-ingress
kubernetes.io/cluster-service: "true"
spec:
replicas: 3
selector:
matchLabels:
app: traefik-ingress
template:
metadata:
labels:
app: traefik-ingress
name: traefik-ingress
spec:
dnsPolicy: ClusterFirstWithHostNet
terminationGracePeriodSeconds: 10
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- traefik-ingress
namespaces:
- kube-system
topologyKey: kubernetes.io/hostname
tolerations:
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 5
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 5
- effect: NoExecute
key: node.kubernetes.io/unschedulable
operator: Exists
tolerationSeconds: 5
- effect: NoExecute
key: node.kubernetes.io/network-unavailable
operator: Exists
tolerationSeconds: 5
serviceAccountName: traefik-ingress
containers:
- image: traefik:v2.4
name: traefik-ingress
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 500m
memory: 500Mi
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- name: dns
containerPort: 53
protocol: UDP
- name: admin
containerPort: 8080
args:
- --configfile=/traefik/traefik.yaml
volumeMounts:
- mountPath: "/traefik"
name: config
volumes:
- name: config
configMap:
name: traefik-config
items:
- key: traefik.yaml
path: traefik.yaml
---
# tls選項
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: traefik-tls-options
namespace: kube-system
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
---
# 存儲分組
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: kube-system
spec:
# 指定默認證書,k8s中traefik只能通過這個指定證書
defaultCertificate:
secretName: traefik-tls
---
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
selector:
app: traefik-ingress
ports:
- port: 80
targetPort: web
name: web
nodePort: 80
- port: 443
targetPort: websecure
name: websecure
nodePort: 443
- port: 53
targetPort: dns
name: dns
nodePort: 53
protocol: UDP
type: NodePort
4、一些注意點
至此,traefik已經(jīng)部署完成,并且支持https,在此過程中,我們需要注意以下幾點:
1、配置文件中配置tls.certificates[]是沒有用的,在k8s中不支持這個配置;
2、TLSStore的name必須叫default;
3、原來使用http時定義了一個IngressRoute,我們使用https還需要再單獨定義一個https的IngressRoute,也就是對于同一個服務(wù),如果需要同時開啟http和https,那么需要定義兩個IngressRoute;
根據(jù)上邊的內(nèi)容,我們可以注意到,在k8s中我們只能配置一個證書,而不能配置多個(實際上IngressRoute中還可以單獨指定一個證書,相當于可以配置多個,不過需要在每個IngressRoute中指定,比較麻煩);
5、定義https的IngressRoute
PS: http的IngressRoute請參考官方示例,比較簡單,這里就不在列舉了;
如下所示:
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: my-service
serviceName: my-service
name: my-service-https
namespace: dev
spec:
# 這里指定https只能走443端口
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`my-service.kube.com`)
services:
- name: my-service
port: 80
# tls相關(guān)配置
tls:
# 如果不想使用全局默認的證書(即上邊TlsStore中存儲的證書),那么可以在IngressRoute所在的命名空間中創(chuàng)建一個secret存放證書,創(chuàng)建方法與上邊相同,然后這里將注釋放開,此時將優(yōu)先使用這里的證書,如果這里的證書不匹配才會用全局默認證書;
# secretName: secret
# tls選項,這里使用我們上邊定義的那個tls選項
options:
name: traefik-tls-options
namespace: kube-system
聯(lián)系我
作者微信:JoeKerouac
微信公眾號(文章會第一時間更新到公眾號,如果搜不出來可能是改名字了,加微信即可=_=|):代碼深度研究院
GitHub:https://github.com/JoeKerouac
