什么是Config机制
在部署Kubernetes https通信环境时,最困难的是各组件的参数的配置,而Kubernetes的Config机制就是为了方便https通信环境搭建的一种手段。组件可以通过读取Config中的内容自动完成密钥参数的配置。
生成认证密钥
要使用https进行通信,首先得需要生成密钥。我的环境是一台虚拟机设备,我把密钥放在/etc/kubernetes/security/serverkey目录下。在生成证书的时候,还使用了多域名机制,方便环境的使用。
修改openssl.cnf
首先拷贝openssl.cnf到/etc/kubernetes/security/serverkey目录下。
cp /etc/ssl/openssl.cnf ./
对openssl.cnf作如下修改,其中[ alt_names ]自己添加。alt_names中表明生成的密钥针对访问kubernetes, k8s, 10.100.0.1(为了能直接使用ServiceAccount,具体IP请根据自己的service网段来配置)的请求有效,alt_names之外的域名都无效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| req_extensions = v3_req [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] DNS.1 = kubernetes DNS.2 = k8s IP.1 = 10.100.0.1
|
生成密钥
首先,在/etc/kubernetes/security/serverkey目录下完成如下命令:
1 2 3
| mkdir -p demoCA/{certs,crl,newcerts,private} touch demoCA/index.txt echo 00 > demoCA/serial
|
在下面步骤中需要输入PEM,要记住此密码。其他信息按照自己的具体情况赶写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| root@fankang:/etc/kubernetes/security/serverkey# openssl req -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf Generating a 2048 bit RSA private key .......................................................................................+++ .......+++ writing new private key to 'ca.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:Zhejiang Locality Name (eg, city) []:Hangzhou Organization Name (eg, company) [Internet Widgits Pty Ltd]:abc Organizational Unit Name (eg, section) []:abc Common Name (e.g. server FQDN or YOUR name) []:abc Email Address []:fankangbest@139.com
|
1 2 3 4 5
| root@fankang:/etc/kubernetes/security/serverkey# openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus ..................+++ ................................+++ e is 65537 (0x10001)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| root@fankang:/etc/kubernetes/security/serverkey# openssl req -new -key server.key -out server.csr -config openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:Zhejiang Locality Name (eg, city) []:Hangzhou Organization Name (eg, company) [Internet Widgits Pty Ltd]:abc Organizational Unit Name (eg, section) []:abc Common Name (e.g. server FQDN or YOUR name) []:abc Email Address []:fankangbest@139.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:123456 An optional company name []:123456
|
在Enter pass phrase for ca.key中输入的是之前我们设置的PEM密码:
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
| root@fankang:/etc/kubernetes/security/serverkey# openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -extensions v3_req -config openssl.cnf Using configuration from openssl.cnf Enter pass phrase for ca.key: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 0 (0x0) Validity Not Before: Jul 9 01:06:49 2017 GMT Not After : Jul 9 01:06:49 2018 GMT Subject: countryName = CN stateOrProvinceName = Zhejiang organizationName = abc organizationalUnitName = abc commonName = abc emailAddress = fankangbest@139.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Alternative Name: DNS:kubernetes, DNS:k8s, IP Address:10.100.0.1 Certificate is to be certified until Jul 9 01:06:49 2018 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
|
现在,在/etc/kubernetes/security/serverkey中有如下文件:
1 2
| root@fankang:/etc/kubernetes/security/serverkey# ls ca.crt ca.key demoCA openssl.cnf server.crt server.csr server.key
|
密钥生成完毕,支持的域名有kubernetes, k8s, 10.100.0.1。
配置config
在Kubernetes中,默认的config文件为/root/.kube/config。在config中写入下面信息即完成config的创建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| apiVersion: v1 kind: Config users: - name: node user: client-certificate: /etc/kubernetes/security/serverkey/server.crt client-key: /etc/kubernetes/security/serverkey/server.key clusters: - name: local cluster: certificate-authority: /etc/kubernetes/security/serverkey/ca.crt server: https://kubernetes:6443 contexts: - context: cluster: local user: node name: my-context current-context: my-context
|
在config文件中,先定义了名为node的user,里面包含了生成好的密钥,然后定义了一个名为local的cluster,接着定义了my-context,最后,我们置my-context生效。
因为我们在config文件中使用了kubernetes作为访问apiserver的入口,但kubernetes域名是不存在的,所以我们需要在主机的/etc/hosts中添加域名kubernetes所对应的IP:
127.0.0.1 kubernetes
起Kubernetes进程
为了方便调试,我都是直接从二进制文件拉起所有服务的:
1 2 3 4 5 6 7 8
| (dockerd -H 0.0.0.0:4243 -H unix:///var/run/docker.sock &>> /var/log/docker.log &) (etcd --data-dir=/home/fankang/data/etcd150/ --listen-client-urls http://0.0.0.0:4001 --advertise-client-urls http://0.0.0.0:4001 &>> /var/log/etcd.log &) (等待20秒再启Kubernetes进程,否则apiserver会因连不上etcd而退出) (kube-apiserver --logtostderr=true --v=0 --etcd-servers=http://localhost:4001 --insecure-bind-address=0.0.0.0 --allow-privileged=false --service-cluster-ip-range=10.100.0.0/16 --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota --client-ca-file=/etc/kubernetes/security/serverkey/ca.crt --tls-private-key-file=/etc/kubernetes/security/serverkey/server.key --tls-cert-file=/etc/kubernetes/security/serverkey/server.crt &>> /var/log/kube-apiserver.log &) (kube-controller-manager --logtostderr=true --v=0 --kubeconfig=/root/.kube/config &>> /var/log/kube-controller-manager.log &) (kube-scheduler --logtostderr=true --v=0 --kubeconfig=/root/.kube/config &>> /var/log/kube-scheduler.log &) (kube-proxy --logtostderr=true --v=0 --kubeconfig=/root/.kube/config &>> /var/log/kube-proxy.log &) (kubelet --logtostderr=true --v=0 --address=0.0.0.0 --allow-privileged=false --pod-infra-container-image=pause:0.8.0 --cpu-cfs-quota=true --kubeconfig=/root/.kube/config --require-kubeconfig=True &>> /var/log/kubelet.log &)
|
kubectl使用Config
Kubectl会直接读取/root/.kube/config中的配置信息和kube-apiserver通信。如果把config中的server改为10.100.0.1:443,那么kubectl就是通过10.100.0.1获取内容的。下面就是更改后kubectl在–v=9时打印出来的日志,kubectl访问的是10.100.0.1:
1
| I0709 10:21:41.636415 21126 round_trippers.go:299] curl -k -v -XGET -H "Accept: application/json" -H "User-Agent: kubectl/v1.5.2+08e0995 (linux/amd64) kubernetes/08e0995" https://10.100.0.1:443/api/v1/namespaces/default/pods
|
总结
感觉Config机制就是把复杂的配置放到Config中,通过node, cluster, context的概念来构造目前环境的配置,这样在使用时就可以屏蔽复杂的细节。