Kubernetes集群安全配置案例

Kubernetes 系统提供了三种认证方式:CA 认证、Token 认证 和 Base 认证。安全功能是一把双刃剑,它保护系统不被攻击,但是也带来额外的性能损耗。集群内的各组件访问 API Server 时,由于它们与 API Server 同时处于同一局域网内,所以建议用非安全的方式访问 API Server 效率更高。

接下来对集群的双向认证配置和简单认证配置过程进行详细说明。

双向认证配置

双向认证方式是最为严格和安全的集群安全配置方式,主要配置流程如下:

  1. 生成根证书、API Server 服务端证书、服务端私钥、各个组件所用的客户端证书和客户端私钥。
  2. 修改 Kubernetes 各个服务进程的启动参数,启用双向认证模式。

详细的配置操作流程如下:

生成根证书

用 openssl 工具生成 CA 证书,请注意将其中 subject 等参数改为用户所需的数据,CN 的值通常是域名、主机名或 IP 地址。

$ cd /var/run/kubernetes
$ openssl genrsa -out dd_ca.key 2048
$ openssl req -x509 -new -nodes -key dd_ca.key -subj "/CN=YOUDOMAIN.COM" -days 5000 -out dd_ca.crt

生成 API Server 服务端证书和私钥

$ openssl genrsa -out dd_server.key 2048
$ HN=`hostname`
$ openssl req -new -key dd_server.key -subj "/CN=$HN" -out dd_server.csr
$ openssl x509 -req -in dd_server.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial-out dd_server.crt -days 5000

生成 Controller Manager 与 Scheduler 进程共用的证书和私钥

$ openssl genrsa -out dd_cs_client.key 2048
$ openssl req -new -key dd_cs_client.key -subj "/CN=$HN" -out dd_cs_client.csr
$ openssl x509 -req -in dd_cs_client.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial -out dd_cs_client.crt -days 5000

生成 Kubelet 所用的客户端证书和私钥

注意,这里假设 Kubelet 所在机器的 IP 地址为 192.168.1.129。

$ openssl genrsa -out dd_kubelet_client.key 2048
$ openssl req -new -key dd_kubelet_client.key -subj "/CN=192.168.1.129" -out dd_kubelet_client.csr
$ openssl x509 -req -in dd_kubelet_client.csr -CA dd_ca.crt -CAkey dd_ca.key -CAcreateserial -out dd_kubelet_client.crt -days 5000

修改 API Server 的启动参数

增加 CA 根证书、Server 自身证书等参数并设置安全端口为 443.

修改/etc/kubernetes/apiserver 配置文件的 KUBE_API_ARGS 参数:

KUBE_API_ARGS="--log-dir=/var/log/kubernetes --secure-port=443 --client_ca_file=/var/run/kubernetes/dd_ca.crt --tls-private-key-file=/var/run/kubernetes/dd_server.key --tls-cert-file=/var/run/kubernetes/dd_server.crt"

重启 kube-apiserver 服务:

# systemctl restart kube-apiserver

验证 API Server 的 HTTPS 服务。

$ curl https://kubernetes-master:443/api/v1/nodes --cert /var/run/kubernetes/dd_cs_client.crt --key /var/run/kubernetes/dd_cs_client.key --cacert /var/run/kubernetes/dd_ca.crt

修改 Controller Manager 的启动参数

修改/etc/kubernetes/controller-manager 配置文件

KUBE_CONTROLLER_MANAGER_ARGS="--log-dir=/var/log/kubernetes --service_account_private_key_file=/var/run/kubernetes/server.key --root-ca-file=/var/run/kubernetes/ca.crt --master=https://kubernetes-master:443 --kubeconfig=/etc/kubernetes/cmkubeconfig"

创建/etc/kubernetes/cmkubeconfig 文件,配置证书等相关参数,具体内容如下:

apiVersion: v1
kind: Config
users
- name: controllermanager
  user:
    client-certificate: /var/run/kubernetes/dd_cs_client.crt
    client-key: /var/run/kubernetes/dd_cs_client.key
clusters:
- name: local
  cluster:
    certificate-authority: /var/run/kubernetes/dd_ca.crt
contexts:
- context:
    cluster: local
    user: controllermanager
  name: my-context
current-context: my-context

重启 kube-controller-manager 服务:

# systemctl restart kube-controller-manager

配置各个节点上的 Kubelet 进程

复制 Kubelet 的证书、私钥 与 CA 根证书到所有 Node 上。

$ scp /var/run/kubernetes/dd_kubelet* root@kubernetes-minion1:/home
$ scp /var/run/kubernetes/dd_ca.* root@kubernetes-minion:/home

在每个 Node 上创建/var/lib/kubelet/kubeconfig 文件,内容如下:

apiVersion: v1
kind: Config
users:
- name: kubelet
  user:
    client-certificats: /home/dd_kubelet_client.crt
    client-key: /home/dd_kubelet_client.key
clusters:
- name: local
  cluster:
    certificate-authority: /home/dd_ca.crt
contexts:
- context:
    cluster: local
    user: kubelet
  name: my-context
current-context: my-context

修改 Kubelet 的启动参数,以修改/etc/kubernetes/kubelet 配置文件为例:

KUBELET_API_SERVER="--api_servers=https://kubernetes-master:443"
KUBELET_ARGS="--pod_infro_container_image=192.168.1.128:1180/google_containers/pause:latest --cluster_dns=10.2.0.100 --cluster_domain=cluster.local --kubeconfig=/var/lib/kubelet/kubeconfig"

重启 kubelet 服务:

# systemctl restart kubelet

配置 kube-proxy

首先,创建/var/lib/kubeproxy/proxykubeconfig 文件,内容如下:

apiVersion: v1
kind: Config
users:
- name: kubeproxy
  user:
    client-certificate: /home/dd_kubelet_client.crt
    client-key: /home/dd_kubelet_client.key
clusters:
- name: local
  cluster:
    certificate-authority: /home/dd_ca.crt
contexts:
- context:
    cluster: local
    user: kubeproxy
  name: my-context
current-context: my-context

然后,修改 kube-proxy 的启动参数,引用上述文件并指明 API Server 在安全模式下的访问地址,以修改配置文件/etc/kubenetes/proxy 为例:

KUBE_PROXY_ARGS="--kubeconfig=/var/lib/kubeproxy/proxykubeconfig --master=https://kubenetes-master:443"

重启 kube-proxy 服务:

# systemctl restart kube-proxy

至此,一个双向认证的 Kubernetes 集群环境就搭建完成了。

简单认证配置

除了双向认证方式,Kubernets 也提供了基于 Token 和 HTTP Base 的简单认证方式。通信方式仍然采用 HTTPS,但不使用数字证书。

采用基于 Token 和 HTTP Base 的简单认证方式时,API Server 对外暴露 HTTPS 端口,客户端提供 Token 或用户名、密码来完成认证过程。这里需要说明的一点是 Kubelet 比较特殊,它同时支持双向认证与简单认证两种模式,其他组件智能配置为双向认证或非安全模式。

API Server 基于 Token 认证的配置过程如下

建立包括用户名、密码和 UID 的文件 token_auth_file:

$ cat /root/token_auth_file
dingmingk,dingmingk,1
admin,admin,2
system,system,3

修改 API Server 的配置,采用上述文件进行安全认证

$ vi /etc/kubernetes/apiserver
KUBE_API_ARGS="--secure-port=443 --token_auth_file=/root/token_auth_file"

重启 API Server 服务

# systemctl restart kube-apiserver

用 curl 验证连接 API Server

$ curl https://kubenetes-master:443/version --header "Authorization: Bearer dingmingk" -k
{
  "major": "1",
  "minor": "0",
  "gitVersion": "v1.0.0",
  "gitCommit": "xxxHASHCODE",
  "gitTreeState": "clean"
}

API Server 基于 HTTP Base 认证的配置过程如下

创建包括用户名、密码和 UID 的文件 basic_auth_file:

$ cat /root/basic_auth_file
dingmingk,dingmingk,1
admin,admin,2
system,system,3

修改 API Server 的配置,采用上述文件进行安全认证

$ vi /etc/kubernetes/apiserver
KUBE_API_ARGS="--secure-port=443 --basic_auth_file=/root/basic_auth_file"

重启 API Server 服务

# systemctl restart kube-apiserver

用 curl 验证连接 API Server

$ curl https://kubernetes-master:443/version --basic -u dingmingk:dingmingk -k
{
  "major": "1",
  "minor": "0",
  "gitVersion": "v1.0.0",
  "gitCommit": "xxxHASHCODE",
  "gitTreeState": "clean"
}

使用 Kubelet 时则需要指定用户名和密码来访问 API Server

$ kubectl get nodes --server="https://kubernetes-master:443" --api-version="v1" --username="dingmingk" --password="dingmingk" --insecure-skip-tls-verify=true

kubectl config set-cluster

在kubeconfig配置文件中设置一个集群项。

摘要

在kubeconfig配置文件中设置一个集群项。 如果指定了一个已存在的名字,将合并新字段并覆盖旧字段。

kubectl config set-cluster NAME [--server=server] [--certificate-authority=path/to/certficate/authority] [--insecure-skip-tls-verify=true]

示例

# 仅设置e2e集群项中的server字段,不影响其他字段
kubectl config set-cluster e2e --server=https://1.2.3.4

# 向e2e集群项中添加认证鉴权数据
kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/kubernetes.ca.crt

# 取消dev集群项中的证书检查
kubectl config set-cluster e2e --insecure-skip-tls-verify=true

选项

      --api-version="": 设置kuebconfig配置文件中集群选项中的api-version。
      --certificate-authority="": 设置kuebconfig配置文件中集群选项中的certificate-authority路径。
      --embed-certs[=false]: 在是否则kubeconfig配置文件中嵌入客户端证书/key。
      --insecure-skip-tls-verify[=false]: 设置kuebconfig配置文件中集群选项中的insecure-skip-tls-verify开关。
      --server="": 设置kuebconfig配置文件中集群选项中的server。

继承自父命令的选项

      --alsologtostderr[=false]: 同时输出日志到标准错误控制台和文件。
      --certificate-authority="": 用以进行认证授权的.cert文件路径。
      --client-certificate="": TLS使用的客户端证书路径。
      --client-key="": TLS使用的客户端密钥路径。
      --cluster="": 指定使用的kubeconfig配置文件中的集群名。
      --context="": 指定使用的kubeconfig配置文件中的环境名。
      --insecure-skip-tls-verify[=false]: 如果为true,将不会检查服务器凭证的有效性,这会导致你的HTTPS链接变得不安全。
      --kubeconfig="": 命令行请求使用的配置文件路径。
      --log-backtrace-at=:0: 当日志长度超过定义的行数时,忽略堆栈信息。
      --log-dir="": 如果不为空,将日志文件写入此目录。
      --log-flush-frequency=5s: 刷新日志的最大时间间隔。
      --logtostderr[=true]: 输出日志到标准错误控制台,不输出到文件。
      --match-server-version[=false]: 要求服务端和客户端版本匹配。
      --namespace="": 如果不为空,命令将使用此namespace。
      --password="": API Server进行简单认证使用的密码。
  -s, --server="": Kubernetes API Server的地址和端口号。
      --stderrthreshold=2: 高于此级别的日志将被输出到错误控制台。
      --token="": 认证到API Server使用的令牌。
      --user="": 指定使用的kubeconfig配置文件中的用户名。
      --username="": API Server进行简单认证使用的用户名。
      --v=0: 指定输出日志的级别。
      --vmodule=: 指定输出日志的模块,格式如下:pattern=N,使用逗号分隔。
时间: 2024-09-27 04:25:30

Kubernetes集群安全配置案例的相关文章

kubernetes集群的认证、授权、准入控制

一.kubernetes集群安全架构 用户使用kubectl.客户机或通过REST请求访问API.可以授权用户和Kubernetes服务帐户进行API访问.当一个请求到达API时,它会经历几个阶段,如下图所示: 1.访问K8S集群的资源需要过三关:认证.鉴权.准入控制: 2.普通用户若要安全访问集群API Server,往往需要证书.Token或者用户名+密码: 3.Pod访问,需要ServiceAccountK8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API S

Centos7上安装Kubernetes集群部署docker

一.安装前准备 1.操作系统详情 需要三台主机,都最小化安装 centos7.3,并update到最新 cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)  角色主机名IP Master      master192.168.1.14 node1    slave-1192.168.1.15 node2slave-2192.168.1.16 2.在每台主机上关闭firewalld改用iptables 输入以下命令,关闭fire

Kubernetes 集群的两种部署过程(daemon部署和容器化部署)以及glusterfs的应用!

ClusterIp:通过VIP来访问, NodePort: 需要自己搭建负载据衡器 LoadBalancer:仅仅用于特定的云提供商 和 Google Container Engine https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/ port:相当于服务端口(对及集群内客户访问) targetPort: 相当于pods端口 nodePort: 宿主机端口(也是服务端口,只不过是对集群外客户访问)

Centos7 下安装入门级别的kubernetes集群

前情说明: 三台Centos7系统的虚拟机(1个master+2个node),三台机器上的防火墙,SELINUX全部关掉.我的实验坏境可以上网,默认的YUM源就可以用. 1.什么是kubernetes Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg).在Docker技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性. Kubernetes优势: - 容器编排         - 轻量级

Shell脚本快速部署Kubernetes集群系统

本文紧跟上节所讲的手动部署Kubernetes管理Docker篇所写,本篇主要内容利用Shell脚本完成快速部署Kubernetes集群.上节博文看过的朋友也能感觉到部署过程相对比较简单,那么,出于简化工作流程,推进运维自动化角度来说,于是花了2/3天时间写这个部署Kubernetes脚本. 运维工作中,常常会遇到部署各种各样的服务,建议:常规部署都应该尽量使用脚本完成,一方面提高自身脚本编写能力,另一方面推进运维自动化. 详细部署说明文档:http://lizhenliang.blog.51c

在kubernetes 集群运行 odoo

kubernetes 可以自动运行多个 odoo服务的副本,因此 非常适用用来做高可用的odoo部署, 在本例中,odoo服务运行在 kubernetes 集群中, 而 postgreSQL 数据库 则 另外运行在 集群宿主主机网络的另外一台主机上 安装kubernetes 集群,方法有很多种,截止到目前,最容易的是 用kubeadm安装, 安装的 步骤参考 http://www.cnblogs.com/odoouse/p/6877766.html 本文主要说明 如何部署 odoo? 要部署一个

基于Python+Django的Kubernetes集群管理平台

原文出自[听云技术博客]:http://blog.tingyun.com/web/article/detail/1345 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调度管理等方面都有其难以言喻的优势,但是随着业务的不断增长,以及服务的多元化,容器的体量与管理的难度也随之增长. 浅述Kubernetes集群日常管理维护中的一些痛点: 1.较为庞大的集群规模及容器数量维护管理

基于kubernetes集群部署DashBoard

在之前一篇文章Centos7部署Kubernetes集群(http://www.cnblogs.com/zhenyuyaodidiao/p/6500830.html)中已经搭建了基本的K8s集群,本文将在此基础之上继续搭建K8s DashBoard. 1.yaml文件 编辑dashboard.yaml,注意或更改以下红色部分: apiVersion: extensions/v1beta1 kind: Deployment metadata: # Keep the name in sync wit

通过Rancher部署并扩容Kubernetes集群基础篇二

接上一篇通过Rancher部署并扩容Kubernetes集群基础篇一 7. 使用ConfigMap配置redis https://github.com/kubernetes/kubernetes.github.io/blob/master/docs/user-guide/configmap/redis/redis-config redis-config maxmemory 2mb     maxmemory-policy allkeys-lru # kubectl create configma