04月17, 2019

Ubuntu18.04离线安装Kubernetes v1.13.4 (带证书)

一、服务器环境

1、配置说明

1)主机内网IP

10.105.125.102

2)kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP)

CLUSTER_KUBERNETES_SVC_IP
172.17.0.1

3)集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)

CLUSTER_DNS_SVC_IP
172.17.0.2

4)服务网段

SERVICE_CIDR
172.17.0.0/16

5)Pod 网段

CLUSTER_CIDR
172.30.0.0/16

2、初始化系统环境

1)主机名

设置永久主机名称,然后重新登录:(云服务器一般不需要设置)

hostnamectl set-hostname master # 将 master 替换为当前主机名

设置的主机名保存在 /etc/hostname 文件中;

如果 DNS 不支持解析主机名称,则需要修改每台机器的 /etc/hosts 文件,添加主机名和 IP 的对应关系:

vim /etc/hosts
10.105.125.102 master

2)无密码 ssh 登录其它节点

ssh-keygen -t rsa
ssh-copy-id root@节点主机名或IP

3)在每台机器上安装依赖包:

apt-get install -y conntrack ipvsadm ipset jq iptables curl sysstat libseccomp-dev
modprobe ip_vs

ipvs 依赖 ipset;

4)关闭防火墙

systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT

5)关闭 swap 分区

如果开启了 swap 分区,kubelet 会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区。同时注释 /etc/fstab 中相应的条目,防止开机自动挂载 swap 分区:

swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

6)关闭 SELinux

关闭 SELinux,否则后续 K8S 挂载目录时可能报错 Permission denied:

setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

7)关闭 dnsmasq(可选)

linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它:

systemctl stop dnsmasq
systemctl disable dnsmasq

8)加载内核模块

modprobe br_netfilter

9)优化内核参数

vim /etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
sysctl -p /etc/sysctl.d/kubernetes.conf

必须关闭 tcp_tw_recycle,否则和 NAT 冲突,会导致服务不通;

关闭 IPV6,防止触发 docker BUG

10)设置系统时区

# 调整系统 TimeZone
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog 
systemctl restart crond

11)更新系统时间

ntpdate cn.pool.ntp.org

12)关闭无关的服务

systemctl stop postfix && systemctl disable postfix

13)创建相关目录

mkdir -p /etc/kubernetes/ssl

14)检查系统内核和模块是否适合运行 docker (仅适用于 linux 系统)

curl -fsSL https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh | bash

15)查看服务错误方法

journalctl -f


二、安装docker

1、安装

export VERSION=18.06
curl -fsSL "https://get.docker.com/" | bash -s -- --mirror Aliyun

2、创建docker配置文件

mkdir -p /etc/docker/
vim /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://fz5yth0r.mirror.aliyuncs.com"],
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

3、重启docker

service docker restart
service docker status


三、下载所需程序

1、下载

wget https://github.com/etcd-io/etcd/releases/download/v3.3.12/etcd-v3.3.12-linux-amd64.tar.gz
wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
wget https://dl.k8s.io/v1.13.4/kubernetes-server-linux-amd64.tar.gz
wget https://dl.k8s.io/v1.13.4/kubernetes-client-linux-amd64.tar.gz
wget https://dl.k8s.io/v1.13.4/kubernetes-node-linux-amd64.tar.gz

2、解压

tar -zxvf etcd-v3.3.12-linux-amd64.tar.gz
tar -zxvf kubernetes-server-linux-amd64.tar.gz
tar -zxvf kubernetes-client-linux-amd64.tar.gz
tar -zxvf kubernetes-node-linux-amd64.tar.gz
mkdir flannel
tar -zxvf flannel-v0.11.0-linux-amd64.tar.gz -C flannel

3、复制可执行文件到指定目录

cp kubernetes/server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl} /usr/local/sbin/
cp kubernetes/node/bin/{kubectl,kubelet,kube-proxy,kubeadm} /usr/local/sbin/
cp etcd-v3.3.12-linux-amd64/{etcd,etcdctl} /usr/local/sbin/
cp flannel/{flanneld,mk-docker-opts.sh} /usr/local/sbin/


四、部署 kubectl 命令行工具

1、创建 kubeconfig 文件

# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kubectl.kubeconfig
  
# 设置客户端认证参数
kubectl config set-credentials admin \
  --client-certificate=/etc/kubernetes/ssl/admin.pem \
  --client-key=/etc/kubernetes/ssl/admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kubectl.kubeconfig
  
# 设置上下文参数
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kubectl.kubeconfig
  
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig

2、复制kubeconfig文件到指定目录

cp kubectl.kubeconfig ~/.kube/config


五、安装etcd

1、创建目录

mkdir -p /etc/etcd /var/lib/etcd/

2、systemd unit 模板文件

vim /lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=/etc/kubernetes/etcd.conf
ExecStart=/usr/local/sbin/etcd \
  --data-dir=${ETCD_DATA_DIR} \
  --wal-dir=${ETCD_WAL_DIR} \
  --name=${ETCD_NAME} \
  --cert-file=/etc/kubernetes/ssl/etcd.pem \
  --key-file=/etc/kubernetes/ssl/etcd-key.pem \
  --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
  --peer-cert-file=/etc/kubernetes/ssl/etcd.pem \
  --peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \
  --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
  --peer-client-cert-auth \
  --client-cert-auth \
  --listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
  --initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
  --listen-client-urls=${ETCD_LISTEN_CLIENT_URLS} \
  --advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
  --initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
  --initial-cluster=${ETCD_INITIAL_CLUSTER} \
  --initial-cluster-state=${ETCD_INITIAL_CLUSTER_STATE} \
  --auto-compaction-mode=periodic \
  --auto-compaction-retention=1 \
  --max-request-bytes=33554432 \
  --quota-backend-bytes=6442450944 \
  --heartbeat-interval=250 \
  --election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target

3、创建环境文件

vim /etc/kubernetes/etcd.conf
#数据存储目录
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
# etcd WAL 目录,建议是 SSD 磁盘分区,或者和 ETCD_DATA_DIR 不同的磁盘分区
ETCD_WAL_DIR="/var/lib/etcd/wal"
#etcd节点名称
ETCD_NAME="master"
#群集通讯URL,此处IP地址为本机IP地址
ETCD_LISTEN_PEER_URLS="https://10.105.125.102:2380"
#供外部客户端使用的url, 此处IP地址为本机IP地址
ETCD_LISTEN_CLIENT_URLS="https://10.105.125.102:2379,https://127.0.0.1:2379"
#广播给集群内其他成员访问的URL 此处IP地址为本机IP地址
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.105.125.102:2380"
#广播给外部客户端使用的url  此处IP地址为本机IP地址
ETCD_ADVERTISE_CLIENT_URLS="https://10.105.125.102:2379"
#初始集群成员列表  此处IP地址为所有节点的名称与对应的IP地址
ETCD_INITIAL_CLUSTER="master=https://10.105.125.102:2380"
#集群名称
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-0"
#初始集群状态,new为新建集群
ETCD_INITIAL_CLUSTER_STATE="new"

WorkingDirectory、--data-dir:指定工作目录和数据目录为 ${ETCD_DATA_DIR},需在启动服务前创建这个目录;

--wal-dir:指定 wal 目录,为了提高性能,一般使用 SSD 或者和 --data-dir 不同的磁盘;

--name:指定节点名称,当 --initial-cluster-state 值为 new 时,--name 的参数值必须位于 --initial-cluster 列表中;

--cert-file、--key-file:etcd server 与 client 通信时使用的证书和私钥;

--trusted-ca-file:签名 client 证书的 CA 证书,用于验证 client 证书;

--peer-cert-file、--peer-key-file:etcd 与 peer 通信使用的证书和私钥;

--peer-trusted-ca-file:签名 peer 证书的 CA 证书,用于验证 peer 证书;

4、启动服务并设置开机启动

systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
systemctl status etcd

5、获取集群状态

etcdctl \
    --endpoints=https://127.0.0.1:2379 \
    --ca-file=/etc/kubernetes/ssl/ca.pem \
    --cert-file=/etc/kubernetes/ssl/etcd.pem \
    --key-file=/etc/kubernetes/ssl/etcd-key.pem cluster-health

6、获取集群节点

etcdctl \
    --endpoints=https://127.0.0.1:2379 \
    --ca-file=/etc/kubernetes/ssl/ca.pem \
    --cert-file=/etc/kubernetes/ssl/etcd.pem \
    --key-file=/etc/kubernetes/ssl/etcd-key.pem member list


六、安装flannel网络

1、向 etcd 写入集群 Pod 网段信息

etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/kubernetes/ssl/flanneld.pem \
  --key-file=/etc/kubernetes/ssl/flanneld-key.pem \
  set /kubernetes/network/config '{"Network": "172.30.0.0/16", "SubnetLen": 24, "SubnetMin": "172.30.0.0","SubnetMax": "172.30.20.0", "Backend": {"Type": "vxlan"}}'

172.30.0.0/16为Pod 网段(CLUSTER_CIDR)

2、创建 flanneld 的 systemd unit 文件

vim /lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
EnvironmentFile=/etc/kubernetes/flanneld.conf
ExecStart=/usr/local/sbin/flanneld \
  -etcd-cafile=/etc/kubernetes/ssl/ca.pem \
  -etcd-certfile=/etc/kubernetes/ssl/flanneld.pem \
  -etcd-keyfile=/etc/kubernetes/ssl/flanneld-key.pem \
  -etcd-endpoints=${ETCD_ENDPOINTS} \
  -etcd-prefix=${FLANNEL_ETCD_PREFIX} \
  -iface=${IFACE} \
  -ip-masq
ExecStartPost=/usr/local/sbin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service

3、创建环境文件

vim /etc/kubernetes/flanneld.conf
ETCD_ENDPOINTS="https://10.105.125.102:2379"
FLANNEL_ETCD_PREFIX="/kubernetes/network"
IFACE="eth0"

10.105.125.102为本机IP

4、启动 flanneld 服务

systemctl daemon-reload
systemctl enable flanneld
systemctl start flanneld
systemctl restart flanneld
systemctl status flanneld

5、查看集群 Pod 网段(/16):

etcdctl \
  --endpoints=https://10.105.125.102:2379 \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/kubernetes/ssl/flanneld.pem \
  --key-file=/etc/kubernetes/ssl/flanneld-key.pem \
  get /kubernetes/network/config

6、查看已分配的 Pod 子网段列表(/24):

etcdctl \
  --endpoints=https://10.105.125.102:2379 \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/kubernetes/ssl/flanneld.pem \
  --key-file=/etc/kubernetes/ssl/flanneld-key.pem \
  ls /kubernetes/network/subnets

7、查看某一 Pod 网段对应的节点 IP 和 flannel 接口地址:

etcdctl \
  --endpoints=https://10.105.125.102:2379 \
  --ca-file=/etc/kubernetes/ssl/ca.pem \
  --cert-file=/etc/kubernetes/ssl/flanneld.pem \
  --key-file=/etc/kubernetes/ssl/flanneld-key.pem \
  get /kubernetes/network/subnets/172.30.9.0-24

8、验证各节点能通过 Pod 网段互通

ip addr show flannel.1|grep -w inet

9、在各节点上 ping 所有 flannel 接口 IP,确保能通

10、查看docker0和flannel.1是否在同一网段

ifconfig

更新docker服务脚本

vim /lib/systemd/system/docker.service

添加

EnvironmentFile=/run/flannel/docker

更新(添加 $DOCKER_NETWORK_OPTIONS 运行参数 )

ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock
systemctl daemon-reload
service docker restart


七、安装kube-apiserver

1、创建加密配置文件

vim encryption-config.yaml
kind: EncryptionConfig
apiVersion: v1
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: G9LgzIHLW3CYwfzorf/eyhWmDUFJ/EOUMOxxnHoUO94=
      - identity: {}
secret为:
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)

2、将加密配置文件拷贝到 master 节点的 /etc/kubernetes 目录下

cp encryption-config.yaml /etc/kubernetes

3、创建kube-apiserver systemd unit 模板文件

vim /lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-apiserver
EnvironmentFile=/etc/kubernetes/kube-apiserver.conf
ExecStart=/usr/local/sbin/kube-apiserver \
  --enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
  --anonymous-auth=false \
  --experimental-encryption-provider-config=/etc/kubernetes/encryption-config.yaml \
  --advertise-address=${ADVERTISE_ADDRESS} \
  --bind-address=${ADVERTISE_ADDRESS} \
  --insecure-port=0 \
  --authorization-mode=Node,RBAC \
  --runtime-config=api/all \
  --enable-bootstrap-token-auth \
  --service-cluster-ip-range=${SERVICE_CIDR} \
  --service-node-port-range=${NODE_PORT_RANGE} \
  --tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
  --tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
  --client-ca-file=/etc/kubernetes/ssl/ca.pem \
  --kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --kubelet-client-certificate=/etc/kubernetes/ssl/kubernetes.pem \
  --kubelet-client-key=/etc/kubernetes/ssl/kubernetes-key.pem \
  --kubelet-https=true \
  --service-account-key-file=/etc/kubernetes/ssl/ca.pem \
  --etcd-cafile=/etc/kubernetes/ssl/ca.pem \
  --etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem \
  --etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem \
  --etcd-servers=${ETCD_ENDPOINTS} \
  --enable-swagger-ui=true \
  --allow-privileged=true \
  --max-mutating-requests-inflight=2000 \
  --max-requests-inflight=4000 \
  --apiserver-count=3 \
  --audit-log-maxage=30 \
  --audit-log-maxbackup=3 \
  --audit-log-maxsize=100 \
  --audit-log-path=/var/lib/kube-apiserver/audit.log \
  --event-ttl=168h \
  --logtostderr=true \
  --v=2
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target

4、创建环境变量

vim /etc/kubernetes/kube-apiserver.conf
ADVERTISE_ADDRESS="0.0.0.0"
SERVICE_CIDR="172.17.0.0/16"
NODE_PORT_RANGE="30000-32767"
ETCD_ENDPOINTS="https://10.105.125.102:2379"

5、创建工作目录

mkdir -p /var/lib/kube-apiserver

6、参数说明

--experimental-encryption-provider-config:启用加密特性;
--authorization-mode=Node,RBAC: 开启 Node 和 RBAC 授权模式,拒绝未授权的请求;
--enable-admission-plugins:启用 ServiceAccount 和 NodeRestriction;
--service-account-key-file:签名 ServiceAccount Token 的公钥文件,kube-controller-manager 的 --service-account-private-key-file 指定私钥文件,两者配对使用;
--tls-*-file:指定 apiserver 使用的证书、私钥和 CA 文件。--client-ca-file 用于验证 client (kue-controller-manager、kube-scheduler、kubelet、kube-proxy 等)请求所带的证书;
--kubelet-client-certificate、--kubelet-client-key:如果指定,则使用 https 访问 kubelet APIs;需要为证书对应的用户(上面 kubernetes*.pem 证书的用户为 kubernetes) 用户定义 RBAC 规则,否则访问 kubelet API 时提示未授权;
--bind-address: 不能为 127.0.0.1,否则外界不能访问它的安全端口 6443;
--insecure-port=0:关闭监听非安全端口(8080);
--service-cluster-ip-range: 指定 Service Cluster IP 地址段;
--service-node-port-range: 指定 NodePort 的端口范围;
--runtime-config=api/all=true: 启用所有版本的 APIs,如 autoscaling/v2alpha1;
--enable-bootstrap-token-auth:启用 kubelet bootstrap 的 token 认证;
--apiserver-count=3:指定集群运行模式,多台 kube-apiserver 会通过 leader 选举产生一个工作节点,其它节点处于阻塞状态;

7、启动kube-apiserver 服务

systemctl daemon-reload
systemctl enable kube-apiserver.service
systemctl start kube-apiserver.service
systemctl status kube-apiserver.service

8、检查集群信息

kubectl cluster-info
kubectl get all --all-namespaces
kubectl get componentstatuses

1)如果执行 kubectl 命令式时输出如下错误信息,则说明使用的 ~/.kube/config 文件不对,请切换到正确的账户后再执行该命令:

  The connection to the server localhost:8080 was refused - did you specify the right host or port?

2)执行 kubectl get componentstatuses 命令时,apiserver 默认向 127.0.0.1 发送请求。当 controller-manager、scheduler 以集群模式运行时,有可能和 kube-apiserver 不在一台机器上,这时 controller-manager 或 scheduler 的状态为 Unhealthy,但实际上它们工作正常。

9、授予 kubernetes 证书访问 kubelet API 的权限

kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes


八、安装kube-controller-manage

1、创建和分发 kubeconfig 文件

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-credentials system:kube-controller-manager \
  --client-certificate=/etc/kubernetes/ssl/kube-controller-manager.pem \
  --client-key=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-context system:kube-controller-manager \
  --cluster=kubernetes \
  --user=system:kube-controller-manager \
  --kubeconfig=kube-controller-manager.kubeconfig
kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
cp kube-controller-manager.kubeconfig /etc/kubernetes/

2、创建kube-controller-manager systemd unit 文件

vim /lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
WorkingDirectory=/var/lib/kube-controller-manager
EnvironmentFile=/etc/kubernetes/kube-controller-manager.conf
ExecStart=/usr/local/sbin/kube-controller-manager \
  --port=0 \
  --secure-port=10252 \
  --bind-address=127.0.0.1 \
  --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
  --authentication-kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
  --authorization-kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
  --service-cluster-ip-range=${SERVICE_CIDR} \
  --cluster-name=kubernetes \
  --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \
  --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --experimental-cluster-signing-duration=8760h \
  --root-ca-file=/etc/kubernetes/ssl/ca.pem \
  --service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
  --leader-elect=true \
  --controllers=*,bootstrapsigner,tokencleaner \
  --horizontal-pod-autoscaler-use-rest-clients=true \
  --horizontal-pod-autoscaler-sync-period=10s \
  --tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \
  --tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
  --use-service-account-credentials=true \
  --kube-api-qps=1000 \
  --kube-api-burst=2000 \
  --logtostderr=true \
  --v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

3、创建环境文件

vim /etc/kubernetes/kube-controller-manager.conf
SERVICE_CIDR="172.17.0.0/16"

4、创建工作目录

mkdir -p /var/lib/kube-controller-manager

5、参数说明

--port=0:关闭监听 http /metrics 的请求,同时 --address 参数无效,--bind-address 参数有效;
--secure-port=10252、--bind-address=0.0.0.0: 在所有网络接口监听 10252 端口的 https /metrics 请求;
--kubeconfig:指定 kubeconfig 文件路径,kube-controller-manager 使用它连接和验证 kube-apiserver;
--authentication-kubeconfig 和 --authorization-kubeconfig:kube-controller-manager 使用它连接 apiserver,对 client 的请求进行认证和授权。kube-controller-manager 不再使用 --tls-ca-file 对请求 https metrics 的 Client 证书进行校验。如果没有配置这两个 kubeconfig 参数,则 client 连接 kube-controller-manager https 端口的请求会被拒绝(提示权限不足)。
--cluster-signing-*-file:签名 TLS Bootstrap 创建的证书;
--experimental-cluster-signing-duration:指定 TLS Bootstrap 证书的有效期;
--root-ca-file:放置到容器 ServiceAccount 中的 CA 证书,用来对 kube-apiserver 的证书进行校验;
--service-account-private-key-file:签名 ServiceAccount 中 Token 的私钥文件,必须和 kube-apiserver 的 --service-account-key-file 指定的公钥文件配对使用;
--service-cluster-ip-range :指定 Service Cluster IP 网段,必须和 kube-apiserver 中的同名参数一致;
--leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
--controllers=*,bootstrapsigner,tokencleaner:启用的控制器列表,tokencleaner 用于自动清理过期的 Bootstrap token;
--horizontal-pod-autoscaler-*:custom metrics 相关参数,支持 autoscaling/v2alpha1;
--tls-cert-file、--tls-private-key-file:使用 https 输出 metrics 时使用的 Server 证书和秘钥;
--use-service-account-credentials=true: kube-controller-manager 中各 controller 使用 serviceaccount 访问 kube-apiserver;

6、启动 kube-controller-manager 服务

systemctl daemon-reload
systemctl enable kube-controller-manager.service 
systemctl start kube-controller-manager.service 
systemctl restart kube-controller-manager.service 
systemctl status kube-controller-manager.service

7、查看输出的 metric

curl --cacert /etc/kubernetes/ssl/ca.pem --cert /etc/kubernetes/ssl/admin.pem --key /etc/kubernetes/ssl/admin-key.pem https://127.0.0.1:10252/metrics

8、查看当前的 leader

kubectl get endpoints kube-controller-manager --namespace=kube-system  -o yaml


九、安装kube-scheduler

1、创建和分发 kubeconfig 文件

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kube-scheduler.kubeconfig
kubectl config set-credentials system:kube-scheduler \
  --client-certificate=/etc/kubernetes/ssl/kube-scheduler.pem \
  --client-key=/etc/kubernetes/ssl/kube-scheduler-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-scheduler.kubeconfig
kubectl config set-context system:kube-scheduler \
  --cluster=kubernetes \
  --user=system:kube-scheduler \
  --kubeconfig=kube-scheduler.kubeconfig
kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
cp kube-scheduler.kubeconfig /etc/kubernetes/

2、创建 kube-scheduler 配置文件

vim kube-scheduler.yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: "/etc/kubernetes/kube-scheduler.kubeconfig"
leaderElection:
  leaderElect: true

--kubeconfig:指定 kubeconfig 文件路径,kube-scheduler 使用它连接和验证 kube-apiserver;

--leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;

cp kube-scheduler.yaml /etc/kubernetes/

3、创建 kube-scheduler systemd unit 文件

vim /lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
WorkingDirectory=/var/lib/kube-scheduler
ExecStart=/usr/local/sbin/kube-scheduler \
  --config=/etc/kubernetes/kube-scheduler.yaml \
  --address=127.0.0.1 \
  --kube-api-qps=100 \
  --logtostderr=true \
  --v=2
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target

--address:在 127.0.0.1:10251 端口接收 http /metrics 请求;kube-scheduler 目前还不支持接收 https 请求;

4、创建工作目录

mkdir -p /var/lib/kube-scheduler

5、启动 kube-scheduler 服务

systemctl daemon-reload
systemctl enable kube-scheduler.service 
systemctl start kube-scheduler.service
systemctl status kube-scheduler.service

6、查看输出的metric

netstat -lnpt|grep kube-sche
curl -s http://127.0.0.1:10251/metrics |head

7、查看当前的leader

kubectl get endpoints kube-scheduler --namespace=kube-system  -o yaml


十、安装kubelet组件

1、创建 kubelet bootstrap kubeconfig 文件

# 创建 token
export BOOTSTRAP_TOKEN=$(kubeadm token create \
  --description kubelet-bootstrap-token \
  --groups system:bootstrappers:master \
  --kubeconfig ~/.kube/config)
# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kubelet-bootstrap-master.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=kubelet-bootstrap-master.kubeconfig
# 设置上下文参数
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kubelet-bootstrap \
  --kubeconfig=kubelet-bootstrap-master.kubeconfig
# 设置默认上下文
kubectl config use-context default --kubeconfig=kubelet-bootstrap-master.kubeconfig
cp kubelet-bootstrap-master.kubeconfig /etc/kubernetes/kubelet-bootstrap.kubeconfig

2、查看 kubeadm 为各节点创建的 token

kubeadm token list --kubeconfig ~/.kube/config

3、查看各 token 关联的 Secret:

kubectl get secrets  -n kube-system|grep bootstrap-token

4、创建 kubelet 参数配置文件

vim kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
  x509:
    clientCAFile: "/etc/kubernetes/ssl/ca.pem"
authorization:
  mode: Webhook
clusterDomain: "cluster.local"
resolvConf: "/run/systemd/resolve/resolv.conf"
clusterDNS:
  - "172.17.0.2"
podCIDR: "172.30.0.0/16"
maxPods: 220
serializeImagePulls: false
hairpinMode: promiscuous-bridge
cgroupDriver: systemd
runtimeRequestTimeout: "15m"
rotateCertificates: true
serverTLSBootstrap: true
readOnlyPort: 0
port: 10250
address: "10.105.125.102"
cp kubelet-config.yaml /etc/kubernetes/

如果系统默认的resolv.conf位置为/etc/resolv.conf,则不需要指定resolvConf

5、创建 kubelet systemd unit 文件

vim /lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/sbin/kubelet \
  --root-dir=/var/lib/kubelet \
  --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \
  --cert-dir=/etc/kubernetes/ssl \
  --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
  --config=/etc/kubernetes/kubelet-config.yaml \
  --hostname-override=master \
  --pod-infra-container-image=registry.cn-beijing.aliyuncs.com/k8s_images/pause-amd64:3.1
  --allow-privileged=true \
  --event-qps=0 \
  --kube-api-qps=1000 \
  --kube-api-burst=2000 \
  --registry-qps=0 \
  --image-pull-progress-deadline=30m \
  --logtostderr=true \
  --v=2
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target

6、创建工作目录

mkdir -p /var/lib/kubelet

7、创建一个 clusterrolebinding,将 group system:bootstrappers 和 clusterrole system:node-bootstrapper 绑定:

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers

8、启动 kubelet 服务

systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl restart kubelet
systemctl status kubelet

9、查看证书状态

kubectl get csr

10、查看节点信息(现在应该看不到节点信息)

kubectl get nodes

11、自动 approve CSR 请求

创建三个 ClusterRoleBinding,分别用于自动 approve client、renew client、renew server 证书:

vim csr-crb.yaml
 # Approve all CSRs for the group "system:bootstrappers"
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: auto-approve-csrs-for-group
 subjects:
 - kind: Group
   name: system:bootstrappers
   apiGroup: rbac.authorization.k8s.io
 roleRef:
   kind: ClusterRole
   name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
   apiGroup: rbac.authorization.k8s.io
---
 # To let a node of the group "system:nodes" renew its own credentials
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: node-client-cert-renewal
 subjects:
 - kind: Group
   name: system:nodes
   apiGroup: rbac.authorization.k8s.io
 roleRef:
   kind: ClusterRole
   name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
   apiGroup: rbac.authorization.k8s.io
---
# A ClusterRole which instructs the CSR approver to approve a node requesting a
# serving cert matching its client cert.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: approve-node-server-renewal-csr
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/selfnodeserver"]
  verbs: ["create"]
---
 # To let a node of the group "system:nodes" renew its own server credentials
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   name: node-server-cert-renewal
 subjects:
 - kind: Group
   name: system:nodes
   apiGroup: rbac.authorization.k8s.io
 roleRef:
   kind: ClusterRole
   name: approve-node-server-renewal-csr
   apiGroup: rbac.authorization.k8s.io

12、生效配置

kubectl apply -f csr-crb.yaml
kubectl delete -f csr-crb.yaml

13、查看 kublet 的情况

kubectl get csr

等待一段时间(1-10 分钟),三个节点的 CSR 都被自动 approved

查看节点信息(应该可以看到节点信息)

kubectl get nodes

14、kube-controller-manager 为各 node 生成了 kubeconfig 文件和公私钥

ll /etc/kubernetes/kubelet.kubeconfig

15、手动 approve server cert csr

kubectl get csr
kubectl certificate approve csr-4mp7h
kubectl certificate approve csr-5pvh6
kubectl certificate approve csr-lbw8q
ll /etc/kubernetes/ssl/kubelet-*

16、kubelet 提供的 API 接口

netstat -lnpt|grep kubelet

17、预定义的 ClusterRole system:kubelet-api-admin 授予访问 kubelet 所有 API 的权限(kube-apiserver 使用的 kubernetes 证书 User 授予了该权限):

kubectl describe clusterrole system:kubelet-api-admin

18、使用部署 kubectl 命令行工具时创建的、具有最高权限的 admin 证书;

curl -s --cacert /etc/kubernetes/ssl/ca.pem --cert /etc/kubernetes/ssl/admin.pem --key /etc/kubernetes/ssl/admin-key.pem https://10.105.125.102:10250/metrics|head

19、cadvisor 统计所在节点各容器的资源(CPU、内存、磁盘、网卡)使用情况

curl -s --cacert /etc/kubernetes/ssl/ca.pem --cert /etc/kubernetes/ssl/admin.pem --key /etc/kubernetes/ssl/admin-key.pem https://10.105.125.102:10250/metrics/cadvisor|head

20、从 kube-apiserver 获取各 node 的配置:

curl -sSL --cacert /etc/kubernetes/ssl/ca.pem --cert /etc/kubernetes/ssl/admin.pem --key /etc/kubernetes/ssl/admin-key.pem https://127.0.0.1:6443/api/v1/nodes/master/proxy/configz | jq \
  '.kubeletconfig|.kind="KubeletConfiguration"|.apiVersion="kubelet.config.k8s.io/v1beta1"'


十一、安装 kube-proxy 组件

1、创建 kubeconfig 文件

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
  --client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
  --client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
cp kube-proxy.kubeconfig /etc/kubernetes/

2、创建 kube-proxy 配置文件

vim kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
  kubeconfig: "/etc/kubernetes/kube-proxy.kubeconfig"
bindAddress: 10.105.125.102
clusterCIDR: 172.30.0.0/16
healthzBindAddress: 10.105.125.102:10256
hostnameOverride: master
metricsBindAddress: 10.105.125.102:10249
mode: "ipvs"
cp kube-proxy-config.yaml /etc/kubernetes

bindAddress: 监听地址;

clientConnection.kubeconfig: 连接 apiserver 的 kubeconfig 文件;

clusterCIDR: kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT;

hostnameOverride: 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;

mode: 使用 ipvs 模式;

3、创建 kube-proxy systemd unit 文件

vim /lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/sbin/kube-proxy \
  --config=/etc/kubernetes/kube-proxy-config.yaml \
  --logtostderr=true \
  --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target

4、创建运行目录

mkdir /var/lib/kube-proxy

5、启动 kube-proxy 服务

systemctl daemon-reload
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status kube-proxy

6、查看监听端口和 metrics

netstat -lnpt|grep kube-prox

7、查看 ipvs 路由规则

ipvsadm -ln


十二、验证集群功能

1、检查节点状态

kubectl get nodes

2、创建测试文件

vim nginx-ds.yml
apiVersion: v1
kind: Service
metadata:
  name: nginx-ds
  labels:
    app: nginx-ds
spec:
  type: NodePort
  selector:
    app: nginx-ds
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ds
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  template:
    metadata:
      labels:
        app: nginx-ds
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

3、执行定义文件

kubectl create -f nginx-ds.yml

4、检查各 Node 上的 Pod IP 连通性

kubectl get pods  -o wide|grep nginx-ds

5、检查服务 IP 和端口可达性

kubectl get svc |grep nginx-ds


十三、安装 coredns 插件

1、修改配置文件

将下载的 kubernetes-server-linux-amd64.tar.gz 解压后,再解压其中的 kubernetes-src.tar.gz 文件。

coredns 对应的目录是:cluster/addons/dns

cd kubernetes/cluster/addons/dns/coredns
cp coredns.yaml.base coredns.yaml
sed -i -e "s/__PILLAR__DNS__DOMAIN__/cluster.local/" -e "s/__PILLAR__DNS__SERVER__/172.17.0.2/" -e "s/k8s.gcr.io\/coredns/coredns\/coredns/" coredns.yaml

2、创建 coredns

kubectl apply -f coredns.yaml
kubectl delete -f coredns.yaml

3、检查 coredns 功能

kubectl get all -n kube-system
kubectl get pods -n kube-system

4、验证 coredns 功能

dig kubernetes.default.svc.cluster.local @172.17.0.2
kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
nslookup kubernetes

5、新建一个 Deployment

vim my-nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  template:
      metadata:
          labels:
           run: my-nginx
      spec:
          containers:
          - name: my-nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
kubectl create -f my-nginx.yaml
kubectl expose deploy my-nginx
kubectl get services --all-namespaces |grep my-nginx

6、创建另一个 Pod,查看 /etc/resolv.conf 是否包含 kubelet 配置的 --cluster-dns 和 --cluster-domain,是否能够将服务 my-nginx 解析到上面显示的 Cluster IP

vim dnsutils-ds.yml
apiVersion: v1
kind: Service
metadata:
  name: dnsutils-ds
  labels:
    app: dnsutils-ds
spec:
  type: NodePort
  selector:
    app: dnsutils-ds
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: dnsutils-ds
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  template:
    metadata:
      labels:
        app: dnsutils-ds
    spec:
      containers:
      - name: my-dnsutils
        image: tutum/dnsutils:latest
        command:
          - sleep
          - "3600"
        ports:
        - containerPort: 80
kubectl create -f dnsutils-ds.yml
kubectl exec dnsutils-ds-c8kcw nslookup kubernetes

7、也可以使用官方github仓库创建coredns.yaml文件

git clone https://github.com/coredns/deployment
cd deployment/kubernetes
./deploy.sh -s -r 172.17.0.0/16 -i 172.17.0.2 -d cluster.local > coredns.yaml


十四、安装 dashboard 插件

1、修改配置文件

将下载的 kubernetes-server-linux-amd64.tar.gz 解压后,再解压其中的 kubernetes-src.tar.gz 文件

dashboard 对应的目录是:cluster/addons/dashboard

cd kubernetes/cluster/addons/dashboard
vim dashboard-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kube-system
  labels:
    k8s-app: kubernetes-dashboard
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  type: NodePort # 增加这一行
  selector:
    k8s-app: kubernetes-dashboard
  ports:
  - port: 443
    targetPort: 8443

增加spec.type: NodePort

2、执行所有定义文件

kubectl create -f  .

3、查看分配的 NodePort

kubectl get deployment kubernetes-dashboard  -n kube-system
kubectl --namespace kube-system get pods -o wide
kubectl get services kubernetes-dashboard -n kube-system

dashboard 的 --authentication-mode 支持 token、basic,默认为 token。如果使用 basic,则 kube-apiserver 必须配置 '--authorization-mode=ABAC' 和 '--basic-auth-file' 参数。

4、查看 dashboard 支持的命令行参数

kubectl exec --namespace kube-system -it kubernetes-dashboard-69db8c7745-jtvpj  -- /dashboard --help # kubernetes-dashboard-69db8c7745-jtvpj 为 pod 名称

5、访问dashboard

为了集群安全,从 1.7 开始,dashboard 只允许通过 https 访问,如果使用 kube proxy 则必须监听 localhost 或 127.0.0.1,对于 NodePort 没有这个限制,但是仅建议在开发环境中使用。

对于不满足这些条件的登录访问,在登录成功后浏览器不跳转,始终停在登录界面

1)kubernetes-dashboard 服务暴露了 NodePort,可以使用 https://NodeIP:NodePort 地址访问 dashboard;
2)通过 kube-apiserver 访问 dashboard;
3)通过 kubectl proxy 访问 dashboard:

查看NodePort端口

kubectl get all -n kube-system

6、通过 kubectl proxy 访问 dashboard

kubectl proxy --address='localhost' --port=8086 --accept-hosts='^*$'

--address 必须为 localhost 或 127.0.0.1;

需要指定 --accept-hosts 选项,否则浏览器访问 dashboard 页面时提示 “Unauthorized”;

7、通过 kube-apiserver 访问 dashboard

获取集群服务地址列表:

kubectl cluster-info

由于 apiserver 通过本地的 kube-nginx 做了代理,所以上面显示的 127.0.0.1:6443 为本地的 kube-nginx 的 IP 和 Port,浏览器访问时需要替换为 kube-apiserver 实际监听的 IP 和端口;

必须通过 kube-apiserver 的安全端口(https)访问 dashbaord,访问时浏览器需要使用自定义证书,否则会被 kube-apiserver 拒绝访问。

创建和导入自定义证书的步骤,

8、创建登录 Dashboard 的 token 和 kubeconfig 配置文件

Dashboard 默认只支持 token 认证,所以如果使用 KubeConfig 文件,需要在该文件中指定 token,不支持使用 client 证书认证。

1)创建登录 token

kubectl create sa dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')
DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}')
echo ${DASHBOARD_LOGIN_TOKEN}

使用输出的 token 登录 Dashboard。

2、创建使用 token 的 KubeConfig 文件

# 设置集群参数

kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=https://127.0.0.1:6443 \
  --kubeconfig=dashboard.kubeconfig

# 设置客户端认证参数,使用上面创建的 Token

kubectl config set-credentials dashboard_user \
  --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tdDJ6MnoiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNmRjMGZkMTYtNjAxZi0xMWU5LTk1NGUtNTI1NDAwODRjN2MxIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.TJDLy-uE1hKVRQmPKyekAPLRsbVGiU7slANsLFr0OFyBW-4hR_ZmGDwtGSRpV4qre7GcMu_UY3L3OvSfRFLTbyqXI3jUnIr6O0hLotTjVIkMPNaoMk_R5y52KZJ2mhrp44AY-cOJ0xzk4EpCwnB3QXcOQ7Ta5JORdZFnJXjiH_4Rhuc_tJeuy92P5eOr1grPSCQO23Go_C4ywTQI4rT6-lBk6IVvu1Iwl1vzVwpiFAnFhPDxiV7U9kkxi9D8aOC8g1ZRTHunueVAklTLSS3MZSoBK9eeKYZ-1SznSmvTCyvHkyK6LdiqODip-pXI7Htg34Mj3gBTOppfijC3cUxVoA \
  --kubeconfig=dashboard.kubeconfig

# 设置上下文参数

kubectl config set-context default \
  --cluster=kubernetes \
  --user=dashboard_user \
  --kubeconfig=dashboard.kubeconfig

# 设置默认上下文

kubectl config use-context default --kubeconfig=dashboard.kubeconfig

3、用生成的 dashboard.kubeconfig 登录 Dashboard。

由于缺少 Heapster 插件,当前 dashboard 不能展示 Pod、Nodes 的 CPU、内存等统计数据和图表;

4、浏览器访问 kube-apiserver 安全端口

1)浏览器访问 kube-apiserver 的安全端口 6443 时,提示证书不被信任:

这是因为 kube-apiserver 的 server 证书是我们创建的根证书 ca.pem 签名的,需要将根证书 ca.pem 导入操作系统,并设置永久信任

2)对于win使用以下命令导入ca.perm

keytool -import -v -trustcacerts -alias appmanagement -file "PATH...\\ca.pem" -storepass password -keystore cacerts

再次访问 https://xxx.xxx.xxx.xxx:6443/,已信任,但提示 401,未授权的访问:

3)我们需要给浏览器生成一个 client 证书,访问 apiserver 的 6443 https 端口时使用。

这里使用部署 kubectl 命令行工具时创建的 admin 证书、私钥和上面的 ca 证书,创建一个浏览器可以使用 PKCS#12/PFX 格式的证书:

openssl pkcs12 -export -out admin.pfx -inkey admin-key.pem -in admin.pem -certfile ca.pem

重启浏览器,再次访问 https://xxx.xxx.xxx.xxx:6443/,提示选择一个浏览器证书,这里选中上面导入的 admin.pfx:

4)被授权访问 kube-apiserver 的安全端口:

客户端选择证书的原理

证书选择是在客户端和服务端 SSL/TLS 握手协商阶段商定的;

服务端如果要求客户端提供证书,则在握手时会向客户端发送一个它接受的 CA 列表;

客户端查找它的证书列表(一般是操作系统的证书,对于 Mac 为 keychain),看有没有被 CA 签名的证书,如果有,则将它们提供给用户选择(证书的私钥);

用户选择一个证书私钥,然后客户端将使用它和服务端通信;

本文链接:https://lxyit.com/article/show/193.html

-- EOF --