kubernetes学习记录(9)——集群基于CA签名的安全设置

最近在使用RC的时候碰到了一个问题:创建RC后无法自动创建Pod 网上搜索,得到出现该问题的原因是:身份认证。 解决的办法有两种:(1)跳过认证(2)解决认证

跳过认证

跳过认证的解决办法是

vim /etc/kubernetes/apiserver

编辑apiserver,去除KUBE_ADMISSION_CONTROL中的 SecurityContextDeny,ServiceAccount 重启kube-apiserver.service服务。

systemctl restart kube-apiserver.service

解决认证

因为后续像Heapster等,都需要与Kubernetes Master进行安全连接,所以使用CA证书解决认证。

本章能创建出一个纯CA认证的集群环境,关闭了所有的非安全端口,这种方式在后续的使用中,碰到了一些问题,正在尝试安全端口和非安全端口并存的认证方式(2017年8月25日备注),成功后会修改本篇内容(已更新)

解决认证采用的是《kubernetes权威指南:从Docker到Kubernetes实践全接触》中的基于CA签名的双向数字证书认证方式。

在一个安全的内网环境中,Kubernetes的各个组件与Master之间可以通过apiserver的非安全端口http://apiserver:8080进行访问。

但如果apiserver需要对外提供服务,或者集群中的某些容器也需要访问apiserver,以获取集群中的某些信息,更安全的做法是启用HTTPS安全机制

这里,采用基于CA签名的双向数字证书认证方式。过程如下:

(1)为kube-apiserver生成一个数字证书,并用CA证书进行签名。
(2)为kube-apiserver进程配置证书相关的启动参数,包括CA证书(用于验证客户端证书的签名真伪、自己经过CA签名后的证书及私钥)。
(3)为每个访问Kubernetes API Server的客户端进程生成自己的数字证书,也都用CA证书进行签名,在相关程序的启动参数中增加CA证书、自己的证书等相关参数。

Master端配置

OpenSSL工具在Master服务器上创建CA证书和私钥相关的文件

#openssl genrsa -out ca.key 2048
#openssl req -x509 -new -nodes -key ca.key -subj "/CN=192.168.121.143" -days 5000 -out ca.crt
#openssl genrsa -out server.key 2048

生成文件如下:

ca.crt  ca.key  server.key

创建Master_ssl.cnf文件,生成x509 v3版本证书

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = master
IP.1 = 10.254.0.1
IP.2 = 192.168.121.143

DNS.5为Master服务器的HostName,IP.1为Kubernetes Master Service的Cluster IP,IP.2为Master服务器的IP。

基于Master_ssl.cnf生成server.csr和server.crt。 在生成server.csr时,-subj参数中/CN指定的名字需要为Master所在的主机名。

openssl req -new -key server.key -subj "/CN=master" -config Master_ssl.cnf -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile Master_ssl.cnf -out server.crt

现在有6个文件:

ca.crt ca.key ca.srl server.crt server.csr server.key

将它们复制到/etc/kubernetes/ssl/下。

配置kube-apiserver的启动参数

修改/etc/kubernetes/apiserver

--client-ca-file #CA根证书文件
--tls-cert-file #服务端证书文件
--tls-private-key-file #服务端私钥文件
--secure-port=6443 #安全端口
--bind-address=192.168.121.143 #HTTPS(安全)绑定的MasterIp地址
--advertise-address=192.168.121.143 #对外提供服务的IP
--insecure-bind-address=192.168.121.143#非安全IP

最终的/etc/kubernetes/apiserver如下

KUBE_API_ADDRESS="--advertise-address=192.168.121.143 --bind-address=192.168.121.143 --insecure-bind-address=192.168.121.143"
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.121.143:2379"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
KUBE_API_ARGS="--client-ca-file=/etc/kubernetes/ssl/ca.crt --tls-private-key-file=/etc/kubernetes/ssl/server.key --tls-cert-file=/etc/kubernetes/ssl/server.crt"

重启kube-apiserver服务

#systemctl restart kube-apiserver

配置kube-controller-manager的启动参数

/etc/kubernetes/controller-manager最终如下

KUBE_CONTROLLER_MANAGER_ARGS="--address=127.0.0.1 --service-account-private-key-file=/etc/kubernetes/ssl/server.key --root-ca-file=/etc/kubernetes/ssl/ca.crt --kubeconfig=/etc/kubernetes/kubeconfig"

配置kube-scheduler的启动参数

/etc/kubernetes/scheduler最终如下

KUBE_SCHEDULER_ARGS="--address=127.0.0.1 --kubeconfig=/etc/kubernetes/kubeconfig"

配置/etc/kubernetes/config

修改/etc/kubernetes/config,最终为

KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=true"
KUBE_MASTER="--master=https//192.168.121.143:6443"

生成集群管理员证书

在/etc/kubernetes/ssl/下执行(会用到上文生成的文件)

#openssl genrsa -out cs_client.key 2048
#openssl req -new -key cs_client.key -subj "/CN=master" -out cs_client.csr
#openssl x509 -req -in cs_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cs_client.crt -days 5000

创建/etc/kubernetes/kubeconfig

apiVersion: v1
kind: Config
users:
- name: controllermanager
  user:
    client-certificate: /etc/kubernetes/ssl/cs_client.crt
    client-key: /etc/kubernetes/ssl/cs_client.key
clusters:
- name: local
  cluster:
    certificate-authority: /etc/kubernetes/ssl/ca.crt
contexts:
- context:
    cluster: local
    user: controllermanager
  name: my-context
current-context: my-context

重启kube-controller-manager、kube-scheduler服务

#systemctl restart kube-scheduler kube-controller-manager

配置Node端

复制kube-apiserver的ca.crt和ca.key到各个Node上(/etc/kubernetes/ssl下)。

生成kubelet_client.crt

在生成kubelet_client.crt时,-CA参数和-CAkey参数使用的是apiserver的ca.crt和ca.key文件。在生成kubelet_client.csr时,-subj参数中的“/CN”设置为本Node的IP地址。

#openssl genrsa -out kubelet_client.key 2048
#openssl req -new -key kubelet_client.key -subj "/CN=192.168.121.144" -out kubelet_client.csr
#openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000

创建/etc/kubernetes/kubeconfig

创建/etc/kubernetes/kubeconfig文件(kubelet和kube-proxy进程共用),配置客户端证书等相关参数。内容如下:

apiVersion: v1
kind: Config
users:
- name: kubelet
  user:
    client-certificate: /etc/kubernetes/ssl/kubelet_client.crt
    client-key: /etc/kubernetes/ssl/kubelet_client.key
clusters:
- name: local
  cluster: 
    certificate-authority: /etc/kubernetes/ssl/ca.crt
contexts:
- context:
    cluster: local
    user: kubelet
  name: my-context
current-context: my-context

修改kubernetes的配置文件/etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=https://192.168.121.143:6443"

设置kubelet服务的启动参数

--api_servers=https://192.168.121.143:6443
--kubeconfig=/etc/kubernetes/kubeconfig

修改/etc/kubernetes/kubelet

KUBELET_ADDRESS="--address=192.168.121.144"
KUBELET_HOSTNAME="--hostname-override=192.168.121.144"
KUBELET_API_SERVER="--api-servers=https://192.168.121.143:6443"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=192.168.121.140:5000/registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS="--cluster_dns=10.254.10.2 --cluster_domain=cluster.local --kubeconfig=/etc/kubernetes/kubeconfig"

重启kubelet服务

#systemctl restart  kubelet

设置kube-proxy服务的启动参数

--master=https://192.168.121.143:6443
--kubeconfig=/etc/kubernetes/kubeconfig

修改/etc/kubernetes/proxy

KUBE_PROXY_ARGS="--master=https://192.168.121.143:6443 --kubeconfig=/etc/kubernetes/kubeconfig"

重启kube-proxy服务

systemctl restart  kube-proxy

验证

我们在正常启动前最好删掉etcd中的旧数据 在master上执行(#etcdctl rm --recursive registry

重启master上的服务

#systemctl daemon-reload
#systemctl restart etcd kube-apiserver kube-scheduler kube-controller-manager

重启node上的服务

#systemctl daemon-reload 
#systemctl restart docker kubelet kube-proxy

验证

#curl https://master:6443/api/v1/nodes --cert /etc/kubernetes/ssl/cs_client.crt --key /etc/kubernetes/ssl/cs_client.key --cacert /etc/kubernetes/ssl/ca.crt
#kubectl get nodes

这里需要配置一下kubectl的启动参数 否则不能直接用kubectl get nodes,直接用会报错

报错信息如下:
The connection to the server localhost:8080 was refused - did you specify the right host or port?

kubectl的启动参数配置会在之后有空的时候整理 使用kubectl -s 192.168.121.143:8080 get nodes代替 下面指令类似

#kubectl get sa --all-namespaces

创建一个RC进行验证

apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-v1
spec:
  replicas: 10
  selector:
    app: myapp
    version: v1
  template:
    metadata:
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: myapp
        command:
          - sleep
          - "3600"
        image: 192.168.121.140:5000/busybox
        imagePullPolicy: IfNotPresent
      restartPolicy: Always

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Golang语言--glog日志库使用

go语言有一个标准库,log,提供了最基本的日志功能,但是没有什么高级的功能,如果需要高级的特性,可以选择glog或log4go。 glog是google提供的...

1.1K9
来自专栏Laoqi's Linux运维专列

K8s集群部署篇–Kube-DNS(三)

2854
来自专栏FreeBuf

Burp XXE Scanner 插件开发(附下载)

Burp没有自带检测XXE漏洞功能,也没有插件。于是自己开始动手撸一个XXE Scanner插件出来。

864
来自专栏菩提树下的杨过

[原创]x.509证书在WCF中的应用(CS篇)

为什么要用x.509证书? WCF的服务端和客户端之间,如果不作任何安全处理(即服务端的<security mode="None">),则所有传输的消息将以明文...

2547
来自专栏一个爱瞎折腾的程序猿

vue项目中关于axios的简单使用

没有vue项目的使用vue-cli脚手架生成一个webpack模板的项目即可愉快的看下去了~ 如果开发遇到跨域问题可以参考:http://www.cnblog...

1961
来自专栏NetCore

保护连接字符串

保护连接字符串 摘自MSDN 保护对数据源的访问是安全应用程序最重要的目标之一。为了帮助限制对数据源的访问,必须保护连接信息(例如用户标识、密码和数据源名称)的...

1805
来自专栏xingoo, 一个梦想做发明家的程序员

获取本机地址信息,遇到小问题...有待解决

程序代码: 1 #include "../common/InitSock.h" 2 #include <stdio.h> 3 CInitSock init...

19010
来自专栏大数据架构师专家

Kubernetes踩坑记---单点集群安装

从今天起,我们开始研究k8s ,之所以叫k8s,是因为Kubernetes这个单词的K和S之间还有8个字母,为了方便书写,就直接用8来代替.国外也会偷懒,这...

681
来自专栏哎_小羊

minikube 安装 Kubernetes Dashboard 并集成 Heapster

目录 Kubernetes Dashboard 介绍 环境、软件准备 Kubernetes Dashboard 安装 Heapster 插件安装 简单演示使用 ...

9098
来自专栏玩转JavaEE

MongoDB基本操作

上篇文章我们简单介绍了MongoDB安装以及启动命令,本文我们来看看基本的增删改查,对MongoDB有一个直观的认识。 ---- 客户端安装配置 上篇文章我们提...

3664

扫码关注云+社区