Google Cloud使用kubernetes,let’s encrypt和nginx-ingress部署web app

环境配置

连接cluster

1
gcloud container clusters get-credentials CLUSER_NAME --zone us-central1-a --project PROJECT_NAME

安装helm和tiller

1
2
3
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller

安装nginx-ingress

1
helm install --name nginx-ingress stable/nginx-ingress --set rbac.create=true --set controller.publishService.enabled=true

安装let’s encrypt

1
2
3
4
5
6
kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

helm repo add jetstack https://charts.jetstack.io
helm install --name cert-manager --namespace cert-manager jetstack/cert-manager

kubectl create -f issuer.yaml

issuer.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: youremail@yourdomain.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
http01: {}

配置DNS

获取nginx-ingress-controller的IP

1
kubectl get svc -n default

output:

1
2
3
4
NAME                            TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
kubernetes ClusterIP 10.64.0.1 <none> 443/TCP 64m
nginx-ingress-controller LoadBalancer 10.64.11.170 35.188.93.188 80:30393/TCP,443:30515/TCP 59m
nginx-ingress-default-backend ClusterIP 10.64.5.162 <none> 80/TCP 59m

将你的DNS记录指向 EXTERNAL-IP -> 35.188.93.188

部署web项目

创建namespace

1
2
kubectl create ns demo
kubectl config set-context $(kubectl config current-context) --namespace=demo

部署项目

Deployment

1
kubectl apply -f deployment.yaml

deplyment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: api-deployment
labels:
app: api
spec:
serviceName: api-app
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
terminationGracePeriodSeconds: 30
containers:
- image: tomcat:8.5.45-jdk8-openjdk-slim
imagePullPolicy: "Always"
name: api
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 150
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 150
periodSeconds: 5

Service

1
kubectl apply -f service.yaml

service.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: api-service
labels:
app: api
spec:
type: ClusterIP
selector:
app: api
ports:
- protocol: TCP
port: 80
targetPort: 8080

Ingress

1
kubectl apply -f ingress.yaml

ingress.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls: # < placing a host in the TLS config will indicate a cert should be created
- hosts:
- demo.w2x.me
secretName: letsencrypt-prod
rules:

- host: demo.w2x.me
http:
paths:
- backend:
serviceName: api-service
servicePort: 80

deploymentpod ready后,访问你配置的域名,就可以看到https加密后的tomcat主页了。

Update

  • 2019-09-08: 添加了let’s encrypt部分缺失的安装步骤。