kubernetes_ingress_letsencrypt

Ingress + Letsencrypt - 图1

申请 Domain Name

首先就是申请一个你要的网域, 这边网路上资源很多都可以查一下哪个网域商或是一些相关的建议, 这边我就先不去多做介绍了, 文章中会以 sam.nctu.me 来作范例

Letsencrypt 来签发凭证

这边我们用手动的把它先签下来, 上 Letsencrypt 去安装 certbot, 手动签的方式也可以参考签 letsencrpyt 凭证 文章, 输入以下指令来签凭证

  1. $ sudo certbot certonly --standalone sam.nctu.me

结果会如下方显示

  1. IMPORTANT NOTES:
  2. - Congratulations! Your certificate and chain have been saved at:
  3. /etc/letsencrypt/live/sam.nctu.me/fullchain.pem
  4. Your key file has been saved at:
  5. /etc/letsencrypt/live/sam.nctu.me/privkey.pem
  6. Your cert will expire on 2017-12-15. To obtain a new or tweaked
  7. version of this certificate in the future, simply run certbot
  8. again. To non-interactively renew *all* of your certificates, run
  9. "certbot renew"
  10. - If you like Certbot, please consider supporting our work by:
  11. Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
  12. Donating to EFF: https://eff.org/donate-le

签好后会自动放在

  1. /etc/letsencrypt/live/sam.nctu.me/

可以看到裡面的凭证, 权限必须是 root 才能看到这个资料夹的内容

  1. # ls
  2. cert.pem chain.pem fullchain.pem privkey.pem README

这样凭证就签完了

设置 Kubernetes Secret

将 fullchain.pem(因为使用 nginx controller) 与 privkey.pem 来建立 secret, 这之后会配置给 ingress 使用

  1. $ kubectl create secret tls tls-certs --cert fullchain.pem --key privkey.pem

查看 secret

  1. $ kubectl get secret
  2. NAME TYPE DATA AGE
  3. default-token-rtlbl kubernetes.io/service-account-token 3 6d
  4. tls-certs kubernetes.io/tls 2 55m

以建立完成

建立 Ingress

我们先去建立一个 ingress 的 yaml 档, 来帮助我们 create ingress 并加入 tls 的设定
ingress.yaml

  1. apiVersion: extensions/v1beta1
  2. kind: Ingress
  3. metadata:
  4. name: nginx-ingress
  5. spec:
  6. tls:
  7. - hosts:
  8. - sam.nctu.me
  9. secretName: tls-certs
  10. rules:
  11. - host: sam.nctu.me
  12. http:
  13. paths:
  14. - backend:
  15. serviceName: phpmyadmin
  16. servicePort: 80

然后建立此 Ingress

  1. $ kubectl create -f ingress.yaml

并查看

  1. $ kubectl get ingress
  2. NAME HOSTS ADDRESS PORTS AGE
  3. nginx-ingress sam.nctu.me 80, 443 1h

建立 default-backend

先建立一个 delfault, 如果试着用 ip 直接 request 或是没有设定过的 domain name, 会回传 404

default-backend.yaml

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. name: default-http-backend
  5. labels:
  6. k8s-app: default-http-backend
  7. namespace: kube-system
  8. spec:
  9. replicas: 1
  10. template:
  11. metadata:
  12. labels:
  13. k8s-app: default-http-backend
  14. spec:
  15. terminationGracePeriodSeconds: 60
  16. containers:
  17. - name: default-http-backend
  18. # Any image is permissable as long as:
  19. # 1. It serves a 404 page at /
  20. # 2. It serves 200 on a /healthz endpoint
  21. image: gcr.io/google_containers/defaultbackend:1.0
  22. livenessProbe:
  23. httpGet:
  24. path: /healthz
  25. port: 8080
  26. scheme: HTTP
  27. initialDelaySeconds: 30
  28. timeoutSeconds: 5
  29. ports:
  30. - containerPort: 8080
  31. resources:
  32. limits:
  33. cpu: 10m
  34. memory: 20Mi
  35. requests:
  36. cpu: 10m
  37. memory: 20Mi
  38. ---
  39. apiVersion: v1
  40. kind: Service
  41. metadata:
  42. name: default-http-backend
  43. namespace: kube-system
  44. labels:
  45. k8s-app: default-http-backend
  46. spec:
  47. ports:
  48. - port: 80
  49. targetPort: 8080
  50. selector:
  51. k8s-app: default-http-backend
  1. $ kubectl create -f default-backend.yaml

建立 Ingress-Nginx-Controller

这边有个小坑, 在建立之前要先设置 RBAC 才会顺利建起来, 花了点时间才发现, 所以我们要先建立相关的 RBAC
ingress-controller-rbac.yaml

  1. apiVersion: rbac.authorization.k8s.io/v1beta1
  2. kind: ClusterRole
  3. metadata:
  4. name: ingress
  5. rules:
  6. - apiGroups:
  7. - ""
  8. resources:
  9. - configmaps
  10. - secrets
  11. - services
  12. - endpoints
  13. - ingresses
  14. - nodes
  15. - pods
  16. verbs:
  17. - list
  18. - watch
  19. - apiGroups:
  20. - "extensions"
  21. resources:
  22. - ingresses
  23. verbs:
  24. - get
  25. - list
  26. - watch
  27. - apiGroups:
  28. - ""
  29. resources:
  30. - events
  31. - services
  32. verbs:
  33. - create
  34. - list
  35. - update
  36. - get
  37. - patch
  38. - apiGroups:
  39. - "extensions"
  40. resources:
  41. - ingresses/status
  42. - ingresses
  43. verbs:
  44. - update
  45. ---
  46. apiVersion: rbac.authorization.k8s.io/v1beta1
  47. kind: Role
  48. metadata:
  49. name: ingress-ns
  50. namespace: kube-system
  51. rules:
  52. - apiGroups:
  53. - ""
  54. resources:
  55. - pods
  56. verbs:
  57. - list
  58. - apiGroups:
  59. - ""
  60. resources:
  61. - services
  62. verbs:
  63. - get
  64. - apiGroups:
  65. - ""
  66. resources:
  67. - endpoints
  68. verbs:
  69. - get
  70. - create
  71. - update
  72. ---
  73. apiVersion: rbac.authorization.k8s.io/v1beta1
  74. kind: RoleBinding
  75. metadata:
  76. name: ingress-ns-binding
  77. namespace: kube-system
  78. roleRef:
  79. apiGroup: rbac.authorization.k8s.io
  80. kind: Role
  81. name: ingress-ns
  82. subjects:
  83. - kind: ServiceAccount
  84. name: ingress
  85. namespace: kube-system
  86. ---
  87. apiVersion: rbac.authorization.k8s.io/v1beta1
  88. kind: ClusterRoleBinding
  89. metadata:
  90. name: ingress-binding
  91. roleRef:
  92. apiGroup: rbac.authorization.k8s.io
  93. kind: ClusterRole
  94. name: ingress
  95. subjects:
  96. - kind: ServiceAccount
  97. name: ingress
  98. namespace: kube-system
  99. ---
  100. apiVersion: v1
  101. kind: ServiceAccount
  102. metadata:
  103. name: ingress
  104. namespace: kube-system
  1. $ kubectl create -f ingress-controller-rbac.yaml

之后就可以建立 Ingress-controller
nginx-ingress-daemonset.yaml

  1. apiVersion: extensions/v1beta1
  2. kind: DaemonSet
  3. metadata:
  4. name: nginx-ingress-controller
  5. labels:
  6. k8s-app: nginx-ingress-controller
  7. namespace: kube-system
  8. spec:
  9. template:
  10. metadata:
  11. labels:
  12. k8s-app: nginx-ingress-controller
  13. spec:
  14. # hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
  15. # however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
  16. # that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
  17. # like with kubeadm
  18. hostNetwork: true
  19. terminationGracePeriodSeconds: 60
  20. serviceAccountName: ingress
  21. containers:
  22. - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.3
  23. name: nginx-ingress-controller
  24. readinessProbe:
  25. httpGet:
  26. path: /healthz
  27. port: 10254
  28. scheme: HTTP
  29. livenessProbe:
  30. httpGet:
  31. path: /healthz
  32. port: 10254
  33. scheme: HTTP
  34. initialDelaySeconds: 10
  35. timeoutSeconds: 1
  36. ports:
  37. - containerPort: 80
  38. hostPort: 80
  39. - containerPort: 443
  40. hostPort: 443
  41. env:
  42. - name: POD_NAME
  43. valueFrom:
  44. fieldRef:
  45. fieldPath: metadata.name
  46. - name: POD_NAMESPACE
  47. valueFrom:
  48. fieldRef:
  49. fieldPath: metadata.namespace
  50. args:
  51. - /nginx-ingress-controller
  52. - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
  1. $ kubectl create -f nginx-ingress-daemonset.yaml

查看是否有建立完成

  1. $ kubectl get pod -n kube-system
  2. nginx-ingress-controller-3q2b0 1/1 Running 0 1h
  3. nginx-ingress-controller-j28sz 1/1 Running 0 1h
  4. nginx-ingress-controller-lrn34 1/1 Running 0 1h

然后再测试 直接输入 https://sam.nctu.tw 就行了, 当然这边只是测试, 记得换成你设定的 domain name

以上相關代碼放在 github