Easy understanding of Kubernetes authentication features

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:

master
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:

master
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  :

master
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官方文档 :

master
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官方文档 :

master
docker run -d \
  --name=scheduler \
  gcr.io/google_containers/kube-scheduler:903b34d5ed7367ec4dddf846675613c9 \
  kube-scheduler \
  --master=192.168.33.17:8080

可以运行以下命令来确认安全配置已经生效:

master
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官方文档 :

node1 node2
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 来登录:

master
~/kubernetes/server/bin/kubectl -s https://192.168.33.17 --insecure-skip-tls-verify=true --username=admin --password=123456 get po

因为8080端口还开着,所以也可以通过http访问:

master
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get po

配置完成后,可以看到系统里有TYPE为 kubernetes.io/service-account-token 的秘密:

master
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get secret

里面有三条数据,分别是 ca.crt , namespace 和 token ,可以通过以下命令看到:

master
~/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需要访问系统服务的时候,就可以使用它们了。可以使用以下命令看到系统的服务账号:

master
~/kubernetes/server/bin/kubectl -s http://192.168.33.17:8080 get serviceAccount

简化kubectl

如果我们通过设置 --insecure-port=0 把api server的http端口关闭,那它就只能通过https访问了:

master
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都得这么麻烦:

master
~/kubernetes/server/bin/kubectl -s https://192.168.33.17 --insecure-skip-tls-verify=true --username=admin --password=123456 get po

幸运的是,kubernetes提供了一种方式,让我们可以大大简化命令,只用这样就好了:

master
~/kubernetes/server/bin/kubectl get po

下面就让我们来试一下吧!首先用 kubectl config 命令来配置admin用户:

master
~/kubernetes/server/bin/kubectl config set-credentials admin --username=admin --password=123456

然后是api server的访问方式,给集群起个名字叫qinghua:

master
~/kubernetes/server/bin/kubectl config set-cluster qinghua --insecure-skip-tls-verify=true --server=https://192.168.33.17

接下来创建一个context,它连接用户admin和集群qinghua:

master
~/kubernetes/server/bin/kubectl config set-context default/qinghua --user=admin --namespace=default --cluster=qinghua

最后设置一下默认的context:

master
~/kubernetes/server/bin/kubectl config use-context default/qinghua

然后就可以用我们的简化版啦:

master
~/kubernetes/server/bin/kubectl get po

可以通过以下命令来看到当前kubectl的配置:

master
~/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 文件里:

master
cat ~/.kube/config

修改这个文件也可以实时生效。细心的童鞋们可以看到,cluster、context和users都是集合,也就是说如果需要切换用户和集群等,只需要设置默认context就可以了,非常方便。

http://www.tuicool.com/articles/byUnQn7

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326527336&siteId=291194637