作者简介
以前外部访问k8s里的服务,都是直接以http方式进行的,缺少TLS安全,今天给大家详细分析一下怎么为k8s加TLS安全访问。
生成并信任自签名证书
首先这里生成自签名的服务器证书,官方介绍了 easyrsa
, openssl
、 cfssl
三个工具,这里使用 cfssl
。
brew install -y cfssl# 生成默认配置文件cfssl print-defaults config > config.jsoncfssl print-defaults csr > csr.json# 生成自定义的config.json文件cp config.json ca-config.json# 生成ca和server的证书请求json文件cp csr.json ca-csr.jsoncp csr.json server-csr.json
编辑 ca-config.json
,内容如下:
{ "signing": { "default": { "expiry": "168h" }, "profiles": { "k8s-local": { "expiry": "8760h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } }}
编辑ca-csr.json,内容如下:
{ "CN": "k8s-local", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "GuangDong", "L": "Shenzhen", "O": "my self signed certificate", "OU": "self signed" } ]}
编辑server-csr.json,内容如下:
{ "CN": "k8s.local", "hosts": [ "127.0.0.1", "*.k8s.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "GuangDong", "L": "Shenzhen", "O": "my self signed certificate", "OU": "self signed" } ]}
执行以下命令,生成CA证书及服务器证书
cfssl gencert -initca ca-csr.json | cfssljson -bare cacfssl gencert -ca=ca.pem -ca-key=ca-key.pem --config=ca-config.json -profile=k8s-local server-csr.json | cfssljson -bare server
这样就得到 ca.pem
, server-key.pem
, server.pem
三个证书文件,其中 ca.pem
是ca的证书, server-key.pem
是服务器证书的密钥, server.pem
是服务器证书。
用 KeychainAccess
打开 ca.pem
文件,然后修改设置,信任该CA,如下图如示:
k8s里使用自签名证书
创建默认的tls secret:
kubectl -n kube-system create secret tls default-tls-cert --key=server-key.pem --cert=server.pem
这里举例,现在有一个服务 k8s-dashboard
,它是以下面的方式部署进k8s的:
helm install --name=local-k8s-dashboard --namespace kube-system stable/kubernetes-dashboard
而该k8s集群已经部署了nginx-ingress-controller,使用的以下命令:
helm install --name local-nginx-ingress stable/nginx-ingress
这里就可以创建 k8s-dashboard
这个服务的ingress规则了,如下:
cat << EOF | kubectl create -f -apiVersion: extensions/v1beta1kind: Ingressmetadata: annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/secure-backends: "true" name: k8s-dashboard-ingress namespace: kube-systemspec: tls: - hosts: - k8s-dashboard.k8s.local secretName: default-tls-cert rules: - host: k8s-dashboard.k8s.local http: paths: - backend: serviceName: local-k8s-dashboard-kubernetes-dashboard servicePort: 443EOF
注意,这里因为 k8s-dashboard
这个服务本身是以https提供服务的,所以才加上了一些与ssl相关的 annotations
,如果只是普通http服务,则不需要这些 annotations
。
最后在chrome浏览器中就可以以 https://k8s-dashboard.k8s.local
访问 k8s-dashboard
服务了,而且浏览器地址栏是安全的绿色哦。
何选nginx-ingress
在上述过程中对比了k8s里两个比较重要的ingress controller:traefik-ingress和nginx-ingress,比较起来,还是nginx-ingress功能更强大,与k8s整合更好一些,看来有k8s官方维护支持果然很强大。
nginx-ingress的用户指南也写得很详细,以后可以多看看。
参考
- https://kubernetes.io/docs/concepts/cluster-administration/certificates/
- https://github.com/helm/charts/blob/master/stable/kubernetes-dashboard
- https://github.com/helm/charts/tree/master/stable/nginx-ingress
- https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls
- https://docs.traefik.io/configuration/backends/kubernetes/