Kubernetes使用Ingress nginx暴露服务并配置证书

发布时间:2020-01-12 13:27:25阅读:(822)

部署配置Ingress

从官网获取配置文件并执行

$ wget -O ingress.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
$ kubectl apply -f ingress.yaml

ingress默认配置没有service-ip,重启之后ingress pod就会改变,因此我们需要通过NodePort或者service将ingress的ip固定下来,我这里使用service实现

$ cat ingress-svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: ingress-service
namespace: ingress-nginx
labels:
name: ingress-service
spec:
ports:
- name: http
port: 80
protocol: TCP
- name: https
port: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
EOF
$ kubectl apply -f ingress-svc.yaml

这里暴露了两个端口,分别对应http,https。 查看service ip:

$ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-service ClusterIP 10.101.25.228 <none> 80/TCP,443/TCP 151m

直接在浏览器中访问http://10.101.25.228,看到以下界面说明配置成功了

HTTPS证书配置

我们使用cert-manager + let's encrypt + 阿里云dns自动生成证书。

首先,安装cert-manager,拉取cert-manager配置文件并执行

$ kubectl create namespace cert-manager
$ wget https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml
$ kubectl apply -f cert-manager.yaml

查看安装结果

$ kubectl get pod -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-5c47f46f57-qjrs2 1/1 Running 0 172m
cert-manager-cainjector-6659d6844d-4wlsq 1/1 Running 0 172m
cert-manager-webhook-547567b88f-k6pgt 1/1 Running 0 172m

$ kubectl get crd | grep cert-manager
certificaterequests.cert-manager.io 2020-01-12T01:53:08Z
certificates.cert-manager.io 2020-01-12T01:53:08Z
challenges.acme.cert-manager.io 2020-01-12T01:53:09Z
clusterissuers.cert-manager.io 2020-01-12T01:53:09Z
issuers.cert-manager.io 2020-01-12T01:53:09Z
orders.acme.cert-manager.io 2020-01-12T01:53:10Z

#验证cert-manager
$ cat <<EOF > test-resources.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: cert-manager-test
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
  name: test-selfsigned
  namespace: cert-manager-test
spec:
  selfSigned: {}
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: selfsigned-cert
  namespace: cert-manager-test
spec:
  commonName: example.com
  secretName: selfsigned-cert-tls
  issuerRef:
    name: test-selfsigned
EOF
$ kubectl apply -f test-resources.yaml
$ kubectl describe certificate -n cert-manager-test # 最后一行看到Certificate issued successfully,就代表安装成功
Events:
  Type    Reason      Age   From          Message
  ----    ------      ----  ----          -------
  Normal  CertIssued  4s    cert-manager  Certificate issued successfully
$ kubectl delete -f test-resources.yaml

安装alidns webhook

$ git clone https://github.com/kevinniu666/cert-manager-webhook-alidns.git
$ helm template --name cert-manager-webhook-alidns --namespace=cert-manager cert-manager-webhook-alidns/deploy/webhook-alidns/ > alidns.yaml # 这里使用了helm,我喜欢使用helm template生成配置文件然后手动执行,这样能清除的看到配置里都写了啥
$ kubectl apply -f alidns.y

查看webhook

$ kubectl get po -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-5c47f46f57-qjrs2 1/1 Running 0 179m
cert-manager-cainjector-6659d6844d-4wlsq 1/1 Running 0 179m
cert-manager-webhook-547567b88f-k6pgt 1/1 Running 0 179m
cert-manager-webhook-alidns-7cdd479b97-htt5f 1/1 Running 1 176m

配置issure

先通过阿里云RAM创建一个账号,并赋予DNSFullAccess权限,建账号额AK,Secret记录下来,这个secret用于webhook在DNS认证的时候,会向DNS解析里面写入一条txt类型的记录

$ kubectl -n cert-manager create secret generic alidns-credentials --from-literal=accessKeySecret='****'
$ cat letsencrypt-clusterissuer.yaml <<EOF
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: 你的邮箱
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- selector:
dnsNames:
- '你的域名,如:*.baidu.com'
dns01:
webhook:
config:
accessKeyId: 账号的AK
accessKeySecretRef:
key: accessKeySecret
name: alidns-credentials
regionId: "cn-shenzhen"
ttl: 600
groupName: certmanager.webhook.alidns
solverName: alidns
EOF
$ kubectl apply -f letsencrypt-clusterissuer.yaml # 执行配置
$ kubectl get clusterissuer # 查看结果
NAME READY AGE
letsencrypt-prod True 3h

配置ingress,这里我使用一个tomcat作为服务

$ cat tomcat.yaml << EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat
namespace: default
annotations:
certmanager.k8s.io/cluster-issuer: "letsencrypt-prod" # 加了这个属性,cert-manager会自动根据域名去创建certificate,order,challenge等
spec:
tls:
- hosts:
- '*.yourdomain.com'
secretName: yourdomain-com-tls
rules:
- host: www.yourdomain.com
http:
paths:
- path: /
backend:
serviceName: tomcat
servicePort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
labels:
component: tomcat
spec:
replicas: 1
selector:
matchLabels:
component: tomcat
template:
metadata:
labels:
component: tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.0.51-alpine
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 0.25
limits:
cpu: 1
ports:
- containerPort: 8080
name: http
livenessProbe:
tcpSocket:
port: http
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 20
timeoutSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: tomcat
labels:
component: tomcat
spec:
selector:
component: tomcat
ports:
- name: http
port: 8080
protocol: TCP
EOF

$ kubectl apply -f tomcat.yaml

查看状态

$ kubectl get ing
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
default tomcat tomcat.***.com 80, 443 3h5m

$ kubectl get certificate, REDAY是True就代表证书从letsencrypt下发成功了。
NAMESPACE NAME READY SECRET AGE
default yourdoman-com-tls True yourdoman-com-tls 3h7m
#如果是false,看看challenge状态,dns的验证需要等一会,为了让txt记录生效,也可以在阿里云控制台查看域名解析情况
$ kubectl get challenge
NAME                            STATE     DOMAIN         AGE
**-tls-2231756264-0             pending   ***.com   5m

等certificate的状态变成true后,就可以访问ingress中的地址了

发表评论

评论列表(有0条评论822人围观)
暂无评论