Kubernetes , or k8s for short, is an open source project led by Google since 2014, providing a container-centric deployment, scaling, and operation and maintenance platform. As of now its latest version is 1.2. Before setting up the environment, it is recommended to understand the relevant knowledge of kubernetes. You can refer to "If there are 10,000 machines, how do you want to play?" " series of articles. This article describes the security configuration of kubernetes.
Ready to work
First, you need to build a kubernetes cluster environment. You can install your own kubernetes cluster by referring to "Easy Building a Kubernetes Version 1.2 Operating Environment" , and run it until the flannel configuration is complete. The parameters set by the api server and other settings can refer to this article.
The result should be that there are three virtual machines, one is called master , its IP is 192.168.33.17 , running k8s api server, controller manager and scheduler; the other two are called node1 and node2 , their IPs are 192.168.33.18 and 192.168.33.19 , running kubelet and kube-proxy of k8s, as two nodes of k8s.
deploy
The easiest way is through CSV-based basic authentication. First, you need to create a basic authentication file for the api server:
cd ~
mkdir security
echo 123456 ,admin,qinghua > security/basic_auth.csv # Format: username, password, user ID
Then you can generate certificates for CA and api server:
cd security
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=192.168.33.17" -days 10000 -out ca.crt
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=192.168.33.17" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000
cd ..
The above command will generate several certificate-related files, which are as follows:
- ca.key: the private key of the CA generated by yourself, used to simulate a CA
- ca.crt: CA certificate self-signed with its own private key
- server.key: the private key of the api server, used to configure the https of the api server
- server.csr: The certificate request file of the api server, used to request the certificate of the api server
- server.crt: The certificate of the api server issued by the CA that you simulate, used to configure the https of the api server
Next, start the api server. For the function of the parameters, please refer to the official documentation of kube-apiserver :
docker run -d \
--name=apiserver \
--net=host \
-v /home/vagrant/security:/security \
gcr.io/google_containers/kube-apiserver:e68c6af15d4672feef7022e94ee4d9af \
kube-apiserver \
--advertise-address=192.168.33.17 \
--admission-control=ServiceAccount \
--insecure-bind-address=0.0.0.0 \
--etcd-servers=http://192.168.33.17:4001 \
--service-cluster-ip-range=11.0.0.0/16 \
--tls-cert-file=/security/server.crt \
--tls-private-key-file=/security/server.key \
--secure-port=443 \
--basic-auth-file=/security/basic_auth.csv
还需要启动controller manager,参数的作用可以参考 kube-controller-manager官方文档 :
docker run -d \
--name=cm \
-v /home/vagrant/security:/security \
gcr.io/google_containers/kube-controller-manager:b9107c794e0564bf11719dc554213f7b \
kube-controller-manager \
--master=192.168.33.17:8080 \
--cluster-cidr=10.245.0.0/16 \
--allocate-node-cidrs=true \
--root-ca-file=/security/ca.crt \
--service-account-private-key-file=/security/server.key
最后是scheduler,参数的作用可以参考 kube-scheduler官方文档 :
docker run -d \
--name=scheduler \
gcr.io/google_containers/kube-scheduler:903b34d5ed7367ec4dddf846675613c9 \
kube-scheduler \
--master=192.168.33.17:8080
可以运行以下命令来确认安全配置已经生效:
curl -k -u admin:123456 https://127.0.0.1/
curl -k -u admin:123456 https://127.0.0.1/api/v1
最后启动kubelet和kube-proxy,参数的作用可以参考 kubelet官方文档 和 kube-proxy官方文档 :
NODE_IP=`ifconfig eth1 | grep 'inet addr:' | cut -d: -f2 | cut -d' ' -f1`
sudo kubernetes/server/bin/kubelet \
--api-servers=192.168.33.17:8080 \
--cluster-dns=11.0.0.10 \
--cluster-domain=cluster.local \
--hostname-override=$NODE_IP \
--node-ip=$NODE_IP > kubelet.log 2>&1 &
sudo kubernetes/server/bin/kube-proxy \
--master=192.168.33.17:8080 \
--hostname-override=$NODE_IP > proxy.log 2>&1 &
验证
如果需要通过https访问,kubectl的命令就略微有点儿麻烦了,需要用 basic_auth.csv
里配置的 admin/123456
来登录:
~/kubernetes/server/bin/kubectl -s https://192.168.33.17 --insecure-skip-tls-verify=true --username=admin --password=123456 get po
因为8080端口还开着,所以也可以通过http访问:
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get po
配置完成后,可以看到系统里有TYPE为 kubernetes.io/service-account-token
的秘密:
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get secret
里面有三条数据,分别是 ca.crt
, namespace
和 token
,可以通过以下命令看到:
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 describe secret
如果你通过kubernetes启动了一个pod,就可以在容器的 /var/run/secrets/kubernetes.io/serviceaccount/
目录里看到以三个文件的形式看到这三条数据(这是 --admission-control=ServiceAccount
的功劳),当pod需要访问系统服务的时候,就可以使用它们了。可以使用以下命令看到系统的服务账号:
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get serviceAccount
简化kubectl
如果我们通过设置 --insecure-port=0
把api server的http端口关闭,那它就只能通过https访问了:
docker rm -f apiserver
docker run -d \
--name=apiserver \
--net=host \
-v /home/vagrant/security:/security \
gcr.io/google_containers/kube-apiserver:e68c6af15d4672feef7022e94ee4d9af \
kube-apiserver \
--advertise-address=192.168.33.17 \
--admission-control=ServiceAccount \
--insecure-bind-address=0.0.0.0 \
--etcd-servers=http://192.168.33.17:4001 \
--service-cluster-ip-range=11.0.0.0/16 \
--tls-cert-file=/security/server.crt \
--tls-private-key-file=/security/server.key \
--secure-port=443 \
--basic-auth-file=/security/basic_auth.csv \
--insecure-port=0
这样的话,就连取个pod都得这么麻烦:
~/kubernetes/server/bin/kubectl -s https://192.168.33.17 --insecure-skip-tls-verify=true --username=admin --password=123456 get po
幸运的是,kubernetes提供了一种方式,让我们可以大大简化命令,只用这样就好了:
~/kubernetes/server/bin/kubectl get po
下面就让我们来试一下吧!首先用 kubectl config
命令来配置admin用户:
~/kubernetes/server/bin/kubectl config set-credentials admin --username=admin --password=123456
然后是api server的访问方式,给集群起个名字叫qinghua:
~/kubernetes/server/bin/kubectl config set-cluster qinghua --insecure-skip-tls-verify=true --server=https://192.168.33.17
接下来创建一个context,它连接用户admin和集群qinghua:
~/kubernetes/server/bin/kubectl config set-context default/qinghua --user=admin --namespace=default --cluster=qinghua
最后设置一下默认的context:
~/kubernetes/server/bin/kubectl config use-context default/qinghua
然后就可以用我们的简化版啦:
~/kubernetes/server/bin/kubectl get po
可以通过以下命令来看到当前kubectl的配置:
~/kubernetes/server/bin/kubectl config view
能够看到如下内容:
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://192.168.33.17
name: qinghua
contexts:
- context:
cluster: qinghua
namespace: default
user: admin
name: default/qinghua
current-context: default/qinghua
kind: Config
preferences: {}
users:
- name: admin
user:
password: "123456"
username: admin
实际上这些配置都存放在 ~/.kube/config
文件里:
cat ~/.kube/config
修改这个文件也可以实时生效。细心的童鞋们可以看到,cluster、context和users都是集合,也就是说如果需要切换用户和集群等,只需要设置默认context就可以了,非常方便。
http://www.tuicool.com/articles/byUnQn7