基础规划

1、IP规划

主机名 IP 配置 软件
master-k8s 10.1.10.128 2C4G etcd,apiserver,controller-manager,scheduler
node01-k8s 10.1.10.129 2C4G etcd,docker,kubelet,kube-proxy
node02-k8s 10.1.10.130 2C4G etcd,docker,kubelet,kube-proxy

2、软件规划

软件名 版本
etcd 3.3.18
docker-ce 19.03.5-3
cfssl 1.2.0
kubernetes 1.16.4
flannel 0.11.0
cni 0.8.3

3、目录规划

目录名 用途
/var/log/kubernetes/ 存储日志
/root/kubernetes/install 安装软件目录
/opt/kubernetes K8S项目部署目录,其中ssl是证书目录,bin是二进制目录,config是配置文件目录
/opt/etcd Etcd项目部署目录,子目录功能如上
/opt/cni cni二进制文件保存目录
/opt/kubernetes/ssl 证书生成目录
/opt/kubernetes/kubeconfig kubeconfig统一生成目录
/opt/kubernetes/system 系统组件YAML文件存储目录
  1. mkdir /var/log/kubernetes /root/kubernetes/{ssl,install,kubeconfig} /root/kubernetes/ssl /opt/etcd/{bin,config,ssl} /opt/kubernetes/{bin,config,ssl} /opt/cni/bin -p

主机初始化配置

2、设置hostname

  1. # 10.1.10.128
  2. hostnamectl set-hostname master-k8s
  3. # 10.1.10.129
  4. hostnamectl set-hostname node01-k8s
  5. # 10.1.10.130
  6. hostnamectl set-hostname node02-k8s

3、配置Hosts(/etc/hosts)

  1. cat >> /etc/hosts <<EOF
  2. 10.1.10.128 master-k8s
  3. 10.1.10.129 node01-k8s
  4. 10.1.10.130 node02-k8s
  5. EOF

4、初始化

关闭防火墙

  1. systemctl stop firewalld
  2. systemctl disable firewalld

关闭SELINUX

  1. setenforce 0
  2. sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/sysconfig/selinux

刷新yum缓存

  1. yum clean all
  2. yum makecache

修改内核参数

  1. cat > /etc/sysctl.d/k8s.conf <<EOF
  2. net.bridge.bridge-nf-call-ip6tables = 1
  3. net.bridge.bridge-nf-call-iptables = 1
  4. net.ipv4.ip_forward = 1
  5. vm.swappiness=0
  6. EOF
  7. modprobe br_netfilter
  8. sysctl -p /etc/sysctl.d/k8s.conf

安装IPVS

  1. cat > /etc/sysconfig/modules/ipvs.modules <<EOF
  2. #!/bin/bash
  3. modprobe -- ip_vs
  4. modprobe -- ip_vs_rr
  5. modprobe -- ip_vs_wrr
  6. modprobe -- ip_vs_sh
  7. modprobe -- nf_conntrack_ipv4
  8. EOF
  9. chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
  10. yum install ipset ipvsadm -y

同步服务器时间

master

  1. #安装chrony:
  2. yum -y install chrony
  3. #注释默认ntp服务器
  4. sed -i 's/^server/#&/' /etc/chrony.conf
  5. #指定上游公共 ntp 服务器,并允许其他节点同步时间
  6. cat >> /etc/chrony.conf << EOF
  7. server 0.asia.pool.ntp.org iburst
  8. server 1.asia.pool.ntp.org iburst
  9. server 2.asia.pool.ntp.org iburst
  10. server 3.asia.pool.ntp.org iburst
  11. allow all
  12. EOF
  13. #重启chronyd服务并设为开机启动:
  14. systemctl enable chronyd && systemctl restart chronyd
  15. #开启网络时间同步功能
  16. timedatectl set-ntp true

slave

  1. #安装chrony:
  2. yum -y install chrony
  3. #注释默认服务器
  4. sed -i 's/^server/#&/' /etc/chrony.conf
  5. #指定内网 master节点为上游NTP服务器
  6. echo 'server 10.1.10.128 iburst' >> /etc/chrony.conf
  7. #重启服务并设为开机启动:
  8. systemctl enable chronyd && systemctl restart chronyd

关闭SWAP分区

  1. swapoff -a
  2. sed -i "s/\/dev\/mapper\/centos-swap/#\/dev\/mapper\/centos-swap/g" /etc/fstab

安装docker

  1. yum install -y yum-utils device-mapper-persistent-data lvm2
  2. yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  3. yum makecache fast
  4. yum install docker-ce -y
  5. systemctl start docker
  6. systemctl enable docker

配置镜像加速()

  1. curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
  2. systemctl restart docker

安装其他软件:

  1. yum install unzip wget lrzsz -y

优化:

  1. vi daemon.json
  2. {
  3. "max-concurrent-downloads": 20,
  4. "log-driver": "json-file",
  5. "bridge": "none",
  6. "oom-score-adjust": -1000,
  7. "debug": false,
  8. "log-opts": {
  9. "max-size": "100M",
  10. "max-file": "10"
  11. },
  12. "default-ulimits": {
  13. "nofile": {
  14. "Name": "nofile",
  15. "Hard": 65535,
  16. "Soft": 65535
  17. },
  18. "nproc": {
  19. "Name": "nproc",
  20. "Hard": 65535,
  21. "Soft": 65535
  22. },
  23. "core": {
  24. "Name": "core",
  25. "Hard": -1,
  26. "Soft": -1
  27. }
  28. }
  29. }

安装cfssl证书生成工具

  1. curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
  2. curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
  3. curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
  4. chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson /usr/local/bin/cfssl-certinfo

搭建ETCD集群

下载地址:https://github.com/etcd-io/etcd/releases/download/v3.3.18/etcd-v3.3.18-linux-amd64.tar.gz

  1. wget https://github.com/etcd-io/etcd/releases/download/v3.3.18/etcd-v3.3.18-linux-amd64.tar.gz

生成ETCD证书

证书生成的目录统一下/root/kubernetes/ssl/下

  1. mkdir /root/kubernetes/ssl/etcd -p && cd /root/kubernetes/ssl/etcd

(1)、创建CA的请求文件(etcd-ca-csr.json)

  1. cat > etcd-ca-csr.json <<EOF
  2. {
  3. "CN": "etcd",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "L": "Chongqing",
  12. "ST": "Chongqing"
  13. }
  14. ]
  15. }
  16. EOF

(2)、创建CA的配置文件(etcd-ca-config.json)

  1. cat > etcd-ca-config.json <<EOF
  2. {
  3. "signing": {
  4. "default": {
  5. "expiry": "87600h"
  6. },
  7. "profiles": {
  8. "www": {
  9. "expiry": "87600h",
  10. "usages": [
  11. "signing",
  12. "key encipherment",
  13. "server auth",
  14. "client auth"
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. EOF

(3)、创建CA证书

  1. cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare etcd-ca -

(4)、创建etcd证书请求文件(etcd-server-csr.json):

  1. cat > etcd-server-csr.json <<EOF
  2. {
  3. "CN": "etcd",
  4. "hosts": [
  5. "10.1.10.128",
  6. "10.1.10.129",
  7. "10.1.10.130"
  8. ],
  9. "key": {
  10. "algo": "rsa",
  11. "size": 2048
  12. },
  13. "names": [
  14. {
  15. "C": "CN",
  16. "L": "Chongqing",
  17. "ST": "Chongqing"
  18. }
  19. ]
  20. }
  21. EOF

(5)、生成etcd证书并用 CA签名

  1. cfssl gencert -ca=etcd-ca.pem -ca-key=etcd-ca-key.pem -config=etcd-ca-config.json -profile=www etcd-server-csr.json | cfssljson -bare etcd-server
  2. # ls *.pem
  3. ca-key.pem ca.pem etcd-key.pem etcd.pem
  4. # cp *.pem /opt/etcd/ssl/

安装ETCD

解压安装包:

  1. tar xf etcd-v3.3.18-linux-amd64.tar.gz
  2. cp etcd etcdctl /opt/etcd/bin/

创建配置文件(etcd.conf)

  1. cat > /opt/etcd/config/etcd.conf <<EOF
  2. #[Member]
  3. ETCD_NAME="etcd-1"
  4. ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
  5. ETCD_LISTEN_PEER_URLS="https://10.1.10.128:2380"
  6. ETCD_LISTEN_CLIENT_URLS="https://10.1.10.128:2379"
  7. #[Clustering]
  8. ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.1.10.128:2380"
  9. ETCD_ADVERTISE_CLIENT_URLS="https://10.1.10.128:2379"
  10. ETCD_INITIAL_CLUSTER="etcd-1=https://10.1.10.128:2380,etcd-2=https://10.1.10.129:2380,etcd-3=https://10.1.10.130:2380"
  11. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  12. ETCD_INITIAL_CLUSTER_STATE="new"
  13. EOF

注意:相应的地址按需更改 ETCD_NAME:三台不能相同 ip地址不能相同

创建etcd的启动文件etcd.service

  1. cat > /usr/lib/systemd/system/etcd.service <<EOF
  2. [Unit]
  3. Description=Etcd Server
  4. After=network.target
  5. After=network-online.target
  6. Wants=network-online.target
  7. [Service]
  8. Type=notify
  9. EnvironmentFile=/opt/etcd/config/etcd.conf
  10. ExecStart=/opt/etcd/bin/etcd \\
  11. --name=\${ETCD_NAME} \\
  12. --data-dir=\${ETCD_DATA_DIR} \\
  13. --listen-peer-urls=\${ETCD_LISTEN_PEER_URLS} \\
  14. --listen-client-urls=\${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \\
  15. --advertise-client-urls=\${ETCD_ADVERTISE_CLIENT_URLS} \\
  16. --initial-advertise-peer-urls=\${ETCD_INITIAL_ADVERTISE_PEER_URLS} \\
  17. --initial-cluster=\${ETCD_INITIAL_CLUSTER} \\
  18. --initial-cluster-token=\${ETCD_INITIAL_CLUSTER_TOKEN} \\
  19. --initial-cluster-state=new \\
  20. --cert-file=/opt/etcd/ssl/etcd-server.pem \\
  21. --key-file=/opt/etcd/ssl/etcd-server-key.pem \\
  22. --peer-cert-file=/opt/etcd/ssl/etcd-server.pem \\
  23. --peer-key-file=/opt/etcd/ssl/etcd-server-key.pem \\
  24. --trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem \\
  25. --peer-trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem
  26. Restart=on-failure
  27. LimitNOFILE=65536
  28. [Install]
  29. WantedBy=multi-user.target
  30. EOF

另外两天部署一样,只有配置文件需要更改一下,将文件拷贝到另外两台:

  1. scp -r /opt/etcd 10.1.10.129:/opt/
  2. scp -r /opt/etcd 10.1.10.130:/opt/
  3. scp /usr/lib/systemd/system/etcd.service 10.1.10.129:/usr/lib/systemd/system/
  4. scp /usr/lib/systemd/system/etcd.service 10.1.10.130:/usr/lib/systemd/system/

然后分别修改配置文件:

10.1.10.129

  1. #[Member]
  2. ETCD_NAME="etcd-2"
  3. ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
  4. ETCD_LISTEN_PEER_URLS="https://10.1.10.129:2380"
  5. ETCD_LISTEN_CLIENT_URLS="https://10.1.10.129:2379"
  6. #[Clustering]
  7. ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.1.10.129:2380"
  8. ETCD_ADVERTISE_CLIENT_URLS="https://10.1.10.129:2379"
  9. ETCD_INITIAL_CLUSTER="etcd-1=https://10.1.10.128:2380,etcd-2=https://10.1.10.129:2380,etcd-3=https://10.1.10.130:2380"
  10. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  11. ETCD_INITIAL_CLUSTER_STATE="new"

10.1.10.130

  1. #[Member]
  2. ETCD_NAME="etcd-3"
  3. ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
  4. ETCD_LISTEN_PEER_URLS="https://10.1.10.130:2380"
  5. ETCD_LISTEN_CLIENT_URLS="https://10.1.10.130:2379"
  6. #[Clustering]
  7. ETCD_INITIAL_ADVERTISE_PEER_URLS="https://10.1.10.130:2380"
  8. ETCD_ADVERTISE_CLIENT_URLS="https://10.1.10.130:2379"
  9. ETCD_INITIAL_CLUSTER="etcd-1=https://10.1.10.128:2380,etcd-2=https://10.1.10.129:2380,etcd-3=https://10.1.10.130:2380"
  10. ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
  11. ETCD_INITIAL_CLUSTER_STATE="new"

然后启动三台的etcd服务

  1. systemctl daemon-reload && systemctl start etcd && systemctl enable etcd

查看集群状态:

  1. /opt/etcd/bin/etcdctl \
  2. --ca-file=/opt/etcd/ssl/etcd-ca.pem --cert-file=/opt/etcd/ssl/etcd-server.pem --key-file=/opt/etcd/ssl/etcd-server-key.pem \
  3. --endpoints="https://10.1.10.128:2379,https://10.1.10.129:2379,https://10.1.10.130:2379" \
  4. cluster-health
  5. member a2dba8836695bcf6 is healthy: got healthy result from https://10.1.10.129:2379
  6. member d1272b0b3cb41282 is healthy: got healthy result from https://10.1.10.128:2379
  7. member e4a3a9c93ef84f2d is healthy: got healthy result from https://10.1.10.130:2379
  8. cluster is healthy

安装Flannel

我是在所有节点都部署了,你也可以只部署Node。

下载地址:https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz

Falnnel要用etcd存储自身一个子网信息,所以要保证能成功连接Etcd,写入预定义子网段:

  1. /opt/etcd/bin/etcdctl --ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/etcd.pem --key-file=/opt/etcd/ssl/etcd-key.pem --endpoints="https://10.1.10.128:2379,https://10.1.10.129:2379,https://10.1.10.130:2379" set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'

然后可以查看一下:

  1. # /opt/etcd/bin/etcdctl --ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/etcd.pem --key-file=/opt/etcd/ssl/etcd-key.pem --endpoints="https://10.1.10.128:2379,https://10.1.10.129:2379,https://10.1.10.130:2379" get /coreos.com/network/config
  2. { "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}

解压压缩包

  1. tar xf flannel-v0.11.0-linux-amd64.tar.gz

将两个重要的二进制文件flanneld和mk-docker-opts.sh拷贝到/opt/kubernetes/bin下

  1. cp flanneld mk-docker-opts.sh /opt/kubernetes/bin/

配置Flannel的配置文件:

  1. cat > /opt/kubernetes/config/flanneld.conf <<EOF
  2. FLANNEL_OPTIONS="\
  3. --etcd-endpoints=https://10.1.10.128:2379,https://10.1.10.129:2379,https://10.1.10.130:2379 \
  4. -etcd-cafile=/opt/etcd/ssl/ca.pem \
  5. -etcd-certfile=/opt/etcd/ssl/etcd.pem \
  6. -etcd-keyfile=/opt/etcd/ssl/etcd-key.pem"
  7. EOF

配置系统systemd启动文件

  1. cat > flanneld.service <<EOF
  2. [Unit]
  3. Description=Flanneld overlay address etcd agent
  4. After=network-online.target network.target
  5. Before=docker.service
  6. [Service]
  7. Type=notify
  8. EnvironmentFile=/opt/kubernetes/config/flanneld.conf
  9. ExecStart=/opt/kubernetes/bin/flanneld --ip-masq $FLANNEL_OPTIONS
  10. ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
  11. Restart=on-failure
  12. [Install]
  13. WantedBy=multi-user.target
  14. EOF

配置Docker的系统文件,指定子网(/usr/lib/systemd/system/docker.service)

  1. [Unit]
  2. Description=Docker Application Container Engine
  3. Documentation=https://docs.docker.com
  4. BindsTo=containerd.service
  5. After=network-online.target firewalld.service containerd.service
  6. Wants=network-online.target
  7. Requires=docker.socket
  8. [Service]
  9. Type=notify
  10. EnvironmentFile=/run/flannel/subnet.env
  11. ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS
  12. ExecReload=/bin/kill -s HUP $MAINPID
  13. TimeoutSec=0
  14. RestartSec=2
  15. Restart=always
  16. StartLimitBurst=3
  17. StartLimitInterval=60s
  18. LimitNOFILE=infinity
  19. LimitNPROC=infinity
  20. LimitCORE=infinity
  21. TasksMax=infinity
  22. Delegate=yes
  23. KillMode=process
  24. [Install]
  25. WantedBy=multi-user.target

将配置文件拷贝到另外主机

  1. cp /opt/kubernetes/flanneld.service /usr/lib/systemd/system/
  2. scp -r /opt/kubernetes/ 10.1.10.129:/opt/
  3. scp -r /opt/kubernetes/ 10.1.10.130:/opt/
  4. scp /usr/lib/systemd/system/{docker,flanneld}.service 10.1.10.129:/usr/lib/systemd/system/
  5. scp /usr/lib/systemd/system/{docker,flanneld}.service 10.1.10.130:/usr/lib/systemd/system/

启动flannel和重启docker

  1. systemctl daemon-reload && systemctl enable flanneld && systemctl start flanneld
  2. systemctl restart docker

检查docker是否使用了flannel网络:

  1. # ps -ef | grep docker
  2. root 10201 1 0 11:08 ? 00:00:00 /usr/bin/dockerd --bip=172.17.69.1/24 --ip-masq=false --mtu=1450

起一个容器测试网络连通性是否正确

  1. # docker run -it --name node02 --rm busybox /bin/sh
  2. / # ip a
  3. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. inet 127.0.0.1/8 scope host lo
  6. valid_lft forever preferred_lft forever
  7. 7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
  8. link/ether 02:42:ac:11:50:02 brd ff:ff:ff:ff:ff:ff
  9. inet 172.17.80.2/24 brd 172.17.80.255 scope global eth0
  10. valid_lft forever preferred_lft forever
  11. / # ping 10.1.10.128 -c 1
  12. PING 10.1.10.128 (10.1.10.128): 56 data bytes
  13. 64 bytes from 10.1.10.128: seq=0 ttl=63 time=0.802 ms
  14. --- 10.1.10.128 ping statistics ---
  15. 1 packets transmitted, 1 packets received, 0% packet loss
  16. round-trip min/avg/max = 0.802/0.802/0.802 ms
  17. / # ping 10.1.10.129 -c 1
  18. PING 10.1.10.129 (10.1.10.129): 56 data bytes
  19. 64 bytes from 10.1.10.129: seq=0 ttl=63 time=0.515 ms
  20. --- 10.1.10.129 ping statistics ---
  21. 1 packets transmitted, 1 packets received, 0% packet loss
  22. round-trip min/avg/max = 0.515/0.515/0.515 ms
  23. / # ping 10.1.10.130 -c 1
  24. PING 10.1.10.130 (10.1.10.130): 56 data bytes
  25. 64 bytes from 10.1.10.130: seq=0 ttl=64 time=0.075 ms
  26. --- 10.1.10.130 ping statistics ---
  27. 1 packets transmitted, 1 packets received, 0% packet loss
  28. round-trip min/avg/max = 0.075/0.075/0.075 ms
  29. / # ping 172.17.7.2 -c 1
  30. PING 172.17.7.2 (172.17.7.2): 56 data bytes
  31. 64 bytes from 172.17.7.2: seq=0 ttl=62 time=0.884 ms
  32. --- 172.17.7.2 ping statistics ---
  33. 1 packets transmitted, 1 packets received, 0% packet loss
  34. round-trip min/avg/max = 0.884/0.884/0.884 ms

安装mater组件

下载地址: https://dl.k8s.io/v1.16.4/kubernetes-server-linux-amd64.tar.gz

  1. mkdir /root/kubernetes/ssl/kubernetes -p

(1)、解压安装压缩文件

  1. tar xf kubernetes-server-linux-amd64.tar.gz

(2)、将我们需要的二进制文件拷贝到我们部署目录中

  1. cp kubernetes/server/bin/{kube-apiserver,kubectlkube-scheduler,kube-controller-manager} /opt/kubernetes/bin/
  2. scp kubernetes/server/bin/{kubelet,kube-proxy} 10.1.10.129:/opt/kubernetes/bin/
  3. scp kubernetes/server/bin/{kubelet,kube-proxy} 10.1.10.130:/opt/kubernetes/bin/

(3)、将其加入环境变量

  1. echo "PATH=/opt/kubernetes/bin/:$PATH" >> /etc/profile
  2. source /etc/profile

(4)、将我们所需的证书和密钥拷贝到部署目录中

由于我们master也准备当Node使用,所以我们将所有证书都拷贝到部署证书目录

  1. cp /root/kubernetes/ssl/kubernetes/*.pem /opt/kubernetes/ssl/

生成证书

创建CA证书

(1)、新建CA配置文件(ca-csr.json)

  1. cat > /root/kubernetes/ssl/kubernetes/ca-csr.json <<EOF
  2. {
  3. "CN": "kubernetes",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "L": "Chongqing",
  12. "ST": "Chongqing",
  13. "O": "kubernetes",
  14. "OU": "System"
  15. }
  16. ]
  17. }
  18. EOF
  1. CN CommonName,kube-apiserver从证书中提取该字段作为请求的用户名(User Name),浏览器使用该字段验证网站是否合法
  2. O Organization,kube-apiserver 从证书中提取该字段作为请求用户和所属组(Group)
  3. kube-apiserver将提取的UserGroup作为RBAC授权的用户和标识

(2)、新建CA配置文件(ca-config.json)

  1. cat > /root/kubernetes/ssl/kubernetes/ca-config.json <<EOF
  2. {
  3. "signing": {
  4. "default": {
  5. "expiry": "87600h"
  6. },
  7. "profiles": {
  8. "kubernetes": {
  9. "expiry": "87600h",
  10. "usages": [
  11. "signing",
  12. "key encipherment",
  13. "server auth",
  14. "client auth"
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. EOF
  1. signing 表示该证书可用于签名其它证书,生成的ca.pem证书找中CA=TRUE
  2. server auth 表示client可以用该证书对server提供的证书进行验证
  3. client auth 表示server可以用该证书对client提供的证书进行验证

(3)、生成CA证书

  1. # cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

创建apiserver证书

(1)、新建apiserver证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/apiserver-csr.json <<EOF
  2. {
  3. "CN": "kubernetes",
  4. "hosts": [
  5. "10.254.0.1",
  6. "127.0.0.1",
  7. "10.1.10.128",
  8. "10.1.10.129",
  9. "10.1.10.130",
  10. "kubernetes",
  11. "kubernetes.default",
  12. "kubernetes.default.svc",
  13. "kubernetes.default.svc.cluster",
  14. "kubernetes.default.svc.cluster.local"
  15. ],
  16. "key": {
  17. "algo": "rsa",
  18. "size": 2048
  19. },
  20. "names": [
  21. {
  22. "C": "CN",
  23. "L": "Chongqing",
  24. "ST": "Chongqing",
  25. "O": "kubernetes",
  26. "OU": "System"
  27. }
  28. ]
  29. }
  30. EOF

(2)、生成证书

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver

创建 Kubernetes webhook 证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/aggregator-csr.json <<EOF
  2. {
  3. "CN": "aggregator",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "kubernetes",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书文件

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes aggregator-csr.json | cfssljson -bare aggregator

创建 Kubernetes admin 证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/admin-csr.json <<EOF
  2. {
  3. "CN": "admin",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "system:masters",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

创建kube-scheduler 证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/kube-scheduler-csr.json <<EOF
  2. {
  3. "CN": "system:kube-scheduler",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "system:kube-scheduler",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书文件和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler

生成kube-controller-manager证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/kube-controller-manager-csr.json <<EOF
  2. {
  3. "CN": "system:kube-controller-manager",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "system:kube-controller-manager",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

创建flannel 证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/flannel-csr.json <<EOF
  2. {
  3. "CN": "flannel",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "system:masters",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes flannel-csr.json | cfssljson -bare flannel

创建kube-proxy证书

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/kube-proxy-csr.json <<EOF
  2. {
  3. "CN": "system:kube-proxy",
  4. "hosts": [],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "system:masters",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书文件

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

创建 kubernetes-dashboard证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/dashboard-csr.json <<EOF
  2. {
  3. "CN": "dashboard",
  4. "hosts": [""],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "L": "Chongqing",
  13. "ST": "Chongqing",
  14. "O": "kubernetes",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF

(2)、生成证书文件和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes dashboard-csr.json | cfssljson -bare dashboard

创建metrics-server 证书配置文件

(1)、创建证书文件

  1. cat > /root/kubernetes/ssl/kubernetes/metrics-server-csr.json <<EOF
  2. {
  3. "CN": "metrics-server",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "CN",
  11. "L": "Chongqing",
  12. "ST": "Chongqing",
  13. "O": "kubernetes",
  14. "OU": "System"
  15. }
  16. ]
  17. }
  18. EOF

(2)、生成证书和私钥

  1. cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes metrics-server-csr.json | cfssljson -bare metrics-server

创建kubeconfig配置文件

在/root/kubernetes/kubeconfig目录下创建这些文件

(1)、设置kube-apiserver环境变量

  1. export KUBE_APISERVER="https://10.1.10.128:6443"

创建admin kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=admin.kubeconfig
  7. # 设置客户端认证参数
  8. kubectl config set-credentials admin \
  9. --client-certificate=../ssl/kubernetes/admin.pem \
  10. --client-key=../ssl/kubernetes/admin-key.pem \
  11. --embed-certs=true \
  12. --kubeconfig=admin.kubeconfig
  13. # 设置上下文参数
  14. kubectl config set-context kubernetes \
  15. --cluster=kubernetes \
  16. --user=admin \
  17. --namespace=kube-system \
  18. --kubeconfig=admin.kubeconfig
  19. # 设置默认上下文
  20. kubectl config use-context kubernetes --kubeconfig=admin.kubeconfig

创建kube-scheduler kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=kube-scheduler.kubeconfig
  7. # 设置客户端认证参数
  8. kubectl config set-credentials system:kube-scheduler \
  9. --client-certificate=../ssl/kubernetes/kube-scheduler.pem \
  10. --embed-certs=true \
  11. --client-key=../ssl/kubernetes/kube-scheduler-key.pem \
  12. --kubeconfig=kube-scheduler.kubeconfig
  13. # 设置上下文参数
  14. kubectl config set-context kubernetes \
  15. --cluster=kubernetes \
  16. --user=system:kube-scheduler \
  17. --kubeconfig=kube-scheduler.kubeconfig
  18. # 设置默认上下文
  19. kubectl config use-context kubernetes --kubeconfig=kube-scheduler.kubeconfig

创建kube-controller-manager kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=kube-controller-manager.kubeconfig
  7. # 设置客户端认证参数
  8. kubectl config set-credentials system:kube-controller-manager \
  9. --client-certificate=../ssl/kubernetes/kube-controller-manager.pem \
  10. --embed-certs=true \
  11. --client-key=../ssl/kubernetes/kube-controller-manager-key.pem \
  12. --kubeconfig=kube-controller-manager.kubeconfig
  13. # 设置上下文参数
  14. kubectl config set-context kubernetes \
  15. --cluster=kubernetes \
  16. --user=system:kube-controller-manager \
  17. --kubeconfig=kube-controller-manager.kubeconfig
  18. # 设置默认上下文
  19. kubectl config use-context kubernetes --kubeconfig=kube-controller-manager.kubeconfig

创建bootstrap kubeconfig

  1. # 生成TOKEN
  2. export TOKEN_ID=$(head -c 6 /dev/urandom | md5sum | head -c 6)
  3. export TOKEN_SECRET=$(head -c 16 /dev/urandom | md5sum | head -c 16)
  4. export BOOTSTRAP_TOKEN=${TOKEN_ID}.${TOKEN_SECRET}
  5. # 设置集群参数
  6. kubectl config set-cluster kubernetes \
  7. --certificate-authority=../ssl/kubernetes/ca.pem \
  8. --embed-certs=true \
  9. --server=${KUBE_APISERVER} \
  10. --kubeconfig=bootstrap.kubeconfig
  11. # 设置客户端认证参数
  12. kubectl config set-credentials system:bootstrap:${TOKEN_ID} \
  13. --token=${BOOTSTRAP_TOKEN} \
  14. --kubeconfig=bootstrap.kubeconfig
  15. # 设置上下文参数
  16. kubectl config set-context default \
  17. --cluster=kubernetes \
  18. --user=system:bootstrap:${TOKEN_ID} \
  19. --kubeconfig=bootstrap.kubeconfig
  20. # 设置默认上下文
  21. kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

BOOTSTRAP_TOKEN=0a22e7.4b91472175b8aaab

创建flannel kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=kubeconfig.conf
  7. # 设置客户端认证参数
  8. kubectl config set-credentials flannel \
  9. --client-certificate=../ssl/kubernetes/flannel.pem \
  10. --client-key=../ssl/kubernetes/flannel-key.pem \
  11. --embed-certs=true \
  12. --kubeconfig=kubeconfig.conf
  13. # 设置上下文参数
  14. kubectl config set-context default \
  15. --cluster=kubernetes \
  16. --user=flannel \
  17. --kubeconfig=kubeconfig.conf
  18. # 设置默认上下文
  19. kubectl config use-context default --kubeconfig=kubeconfig.conf

创建kube-proxy kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=kube-proxy.kubeconfig
  7. # 设置客户端认证参数
  8. kubectl config set-credentials system:kube-proxy \
  9. --client-certificate=../ssl/kubernetes/kube-proxy.pem \
  10. --client-key=../ssl/kubernetes/kube-proxy-key.pem \
  11. --embed-certs=true \
  12. --kubeconfig=kube-proxy.kubeconfig
  13. # 设置上下文参数
  14. kubectl config set-context default \
  15. --cluster=kubernetes \
  16. --user=system:kube-proxy \
  17. --kubeconfig=kube-proxy.kubeconfig
  18. # 设置默认上下文
  19. kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

创建组件配置文件

创建kube-apiserver配置文件

(1)、创建主配置文件

  1. cat > /opt/kubernetes/config/kube-apiserver.conf <<EOF
  2. KUBE_APISERVER_OPTS="--logtostderr=false \\
  3. --bind-address=10.1.10.128 \\
  4. --advertise-address=10.1.10.128 \\
  5. --secure-port=6443 \\
  6. --insecure-port=0 \\
  7. --service-cluster-ip-range=10.254.0.0/16 \\
  8. --service-node-port-range=20000-40000 \\
  9. --etcd-cafile=/opt/etcd/ssl/etcd-ca.pem \\
  10. --etcd-certfile=/opt/etcd/ssl/etcd-server.pem \\
  11. --etcd-keyfile=/opt/etcd/ssl/etcd-server-key.pem \\
  12. --etcd-prefix=/registry \\
  13. --etcd-servers=https://10.1.10.128:2379,https://10.1.10.129:2379,https://10.1.10.130:2379 \\
  14. --client-ca-file=/opt/kubernetes/ssl/ca.pem \\
  15. --tls-cert-file=/opt/kubernetes/ssl/apiserver.pem\\
  16. --tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \\
  17. --kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \\
  18. --kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \\
  19. --service-account-key-file=/opt/kubernetes/ssl/ca.pem \\
  20. --requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
  21. --proxy-client-cert-file=/opt/kubernetes/ssl/aggregator.pem \\
  22. --proxy-client-key-file=/opt/kubernetes/ssl/aggregator-key.pem \\
  23. --requestheader-allowed-names=aggregator \\
  24. --requestheader-group-headers=X-Remote-Group \\
  25. --requestheader-extra-headers-prefix=X-Remote-Extra- \\
  26. --requestheader-username-headers=X-Remote-User \\
  27. --enable-aggregator-routing=true \\
  28. --anonymous-auth=false \\
  29. --allow-privileged=true \\
  30. --experimental-encryption-provider-config=/opt/kubernetes/config/encryption-config.yaml \\
  31. --enable-admission-plugins=DefaultStorageClass,DefaultTolerationSeconds,LimitRanger,NamespaceExists,NamespaceLifecycle,NodeRestriction,OwnerReferencesPermissionEnforcement,PodNodeSelector,PersistentVolumeClaimResize,PodPreset,PodTolerationRestriction,ResourceQuota,ServiceAccount,StorageObjectInUseProtection MutatingAdmissionWebhook ValidatingAdmissionWebhook \\
  32. --disable-admission-plugins=DenyEscalatingExec,ExtendedResourceToleration,ImagePolicyWebhook,LimitPodHardAntiAffinityTopology,NamespaceAutoProvision,Priority,EventRateLimit,PodSecurityPolicy \\
  33. --cors-allowed-origins=.* \\
  34. --enable-swagger-ui \\
  35. --runtime-config=api/all=true \\
  36. --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \\
  37. --authorization-mode=Node,RBAC \\
  38. --apiserver-count=1 \\
  39. --audit-log-maxage=30 \\
  40. --audit-log-maxbackup=3 \\
  41. --audit-log-maxsize=100 \\
  42. --kubelet-https \\
  43. --event-ttl=1h \\
  44. --feature-gates=RotateKubeletServerCertificate=true,RotateKubeletClientCertificate=true \\
  45. --enable-bootstrap-token-auth=true \\
  46. --audit-log-path=/var/log/kubernetes/api-server-audit.log \\
  47. --alsologtostderr=true \\
  48. --log-dir=/var/log/kubernetes \\
  49. --v=2 \\
  50. --endpoint-reconciler-type=lease \\
  51. --max-mutating-requests-inflight=100 \\
  52. --max-requests-inflight=500 \\
  53. --target-ram-mb=6000"
  54. EOF

(2)、创建encryption-config.yaml

  1. export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
  2. cat > /opt/kubernetes/config/encryption-config.yaml <<EOF
  3. kind: EncryptionConfig
  4. apiVersion: v1
  5. resources:
  6. - resources:
  7. - secrets
  8. providers:
  9. - aescbc:
  10. keys:
  11. - name: key1
  12. secret: ${ENCRYPTION_KEY}
  13. - identity: {}
  14. EOF

创建kube-controller-manager配置文件

  1. cat > /opt/kubernetes/config/kube-controller-manager.conf <<EOF
  2. KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
  3. --leader-elect=true \\
  4. --address=0.0.0.0 \\
  5. --service-cluster-ip-range=10.254.0.0/16 \\
  6. --cluster-cidr=172.20.0.0/16 \\
  7. --node-cidr-mask-size=24 \\
  8. --cluster-name=kubernetes \\
  9. --allocate-node-cidrs=true \\
  10. --kubeconfig=/opt/kubernetes/config/kube-controller-manager.kubeconfig \\
  11. --authentication-kubeconfig=/opt/kubernetes/config/kube-controller-manager.kubeconfig \\
  12. --authorization-kubeconfig=/opt/kubernetes/config/kube-controller-manager.kubeconfig \\
  13. --use-service-account-credentials=true \\
  14. --client-ca-file=/opt/kubernetes/ssl/ca.pem \\
  15. --requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
  16. --node-monitor-grace-period=40s \\
  17. --node-monitor-period=5s \\
  18. --pod-eviction-timeout=5m0s \\
  19. --terminated-pod-gc-threshold=50 \\
  20. --alsologtostderr=true \\
  21. --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
  22. --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
  23. --deployment-controller-sync-period=10s \\
  24. --experimental-cluster-signing-duration=86700h0m0s \\
  25. --enable-garbage-collector=true \\
  26. --root-ca-file=/opt/kubernetes/ssl/ca.pem \\
  27. --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
  28. --feature-gates=RotateKubeletServerCertificate=true,RotateKubeletClientCertificate=true \\
  29. --controllers=*,bootstrapsigner,tokencleaner \\
  30. --horizontal-pod-autoscaler-use-rest-clients=true \\
  31. --horizontal-pod-autoscaler-sync-period=10s \\
  32. --tls-cert-file=/opt/kubernetes/ssl/kube-controller-manager.pem \\
  33. --tls-private-key-file=/opt/kubernetes/ssl/kube-controller-manager-key.pem \\
  34. --kube-api-qps=100 \\
  35. --kube-api-burst=100 \\
  36. --log-dir=/var/log/kubernetes \\
  37. --v=2"
  38. EOF

创建kube-scheduler配置文件

  1. cat > /opt/kubernetes/config/kube-scheduler.conf <<EOF
  2. KUBE_SCHEDULER_OPTS=" \\
  3. --logtostderr=false \\
  4. --address=0.0.0.0 \\
  5. --leader-elect=true \\
  6. --kubeconfig=/opt/kubernetes/config/kube-scheduler.kubeconfig \\
  7. --authentication-kubeconfig=/opt/kubernetes/config/kube-scheduler.kubeconfig \\
  8. --authorization-kubeconfig=/opt/kubernetes/config/kube-scheduler.kubeconfig \\
  9. --alsologtostderr=true \\
  10. --kube-api-qps=100 \\
  11. --kube-api-burst=100 \\
  12. --log-dir=/var/log/kubernetes \\
  13. --v=2"
  14. EOF

创建kubelet配置文件

在node节点上创建

  1. cat > /opt/kubernetes/config/kubelet.conf <<EOF
  2. KUBELET_OPTS="--logtostderr=true \\
  3. --v=4 \\
  4. --network-plugin=cni \\
  5. --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin \\
  6. --hostname-override=10.1.10.129 \\
  7. --kubeconfig=/opt/kubernetes/config/kubelet.kubeconfig \\
  8. --bootstrap-kubeconfig=/opt/kubernetes/config/bootstrap.kubeconfig \\
  9. --config=/opt/kubernetes/config/kubelet.yaml \\
  10. --cert-dir=/opt/kubernetes/ssl \\
  11. --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/rookieops/pause-amd64:3.0"
  12. EOF

address: 节点IP,不同节点需要更改 node-ip:节点IP,不同节点需要更改 hostname-override:节点hostname,也可以配置节点IP,不同节点需要更改 healthz-bind-address:节点IP,不同节点需要更改 —hostname-override 在集群中显示的主机名,其他节点需要更改 —kubeconfig 指定kubeconfig文件位置,会自动生成 —bootstrap-kubeconfig 指定刚才生成的bootstrap.kubeconfig文件 —cert-dir 颁发证书存放位置 —pod-infra-container-image 管理Pod网络的镜像

创建kubelet.yaml配置文件

  1. cat > /opt/kubernetes/config/kubelet.yaml <<EOF
  2. kind: KubeletConfiguration
  3. apiVersion: kubelet.config.k8s.io/v1beta1
  4. address: 10.1.10.129
  5. port: 10250
  6. readOnlyPort: 10255
  7. cgroupDriver: cgroupfs
  8. clusterDNS: ["10.254.0.2"]
  9. clusterDomain: cluster.local.
  10. failSwapOn: false
  11. authentication:
  12. anonymous:
  13. enabled: false
  14. webhook:
  15. cacheTTL: 2m0s
  16. enabled: true
  17. x509:
  18. clientCAFile: /opt/kubernetes/ssl/ca.pem
  19. authorization:
  20. mode: Webhook
  21. webhook:
  22. cacheAuthorizedTTL: 5m0s
  23. cacheUnauthorizedTTL: 30s
  24. evictionHard:
  25. imagefs.available: 15%
  26. memory.available: 100Mi
  27. nodefs.available: 10%
  28. nodefs.inodesFree: 5%
  29. maxOpenFiles: 1000000
  30. maxPods: 110
  31. EOF

不同节点需要修改的地方为IP

创建kube-proxy配置文件

  1. cat > /opt/kubernetes/config/kube-proxy.conf <<EOF
  2. KUBE_PROXY_OPTS="--logtostderr=false \\
  3. --v=2 \\
  4. --feature-gates=SupportIPVSProxyMode=true \\
  5. --masquerade-all=true \\
  6. --proxy-mode=ipvs \\
  7. --ipvs-min-sync-period=5s \\
  8. --ipvs-sync-period=5s \\
  9. --ipvs-scheduler=rr \\
  10. --cluster-cidr=172.20.0.0/16 \\
  11. --log-dir=/var/log/kubernetes \\
  12. --kubeconfig=/opt/kubernetes/config/kube-proxy.kubeconfig"
  13. EOF

创建组件systemd启动文件

创建kube-apiserver启动文件

  1. cat > /usr/lib/systemd/system/kube-apiserver.service <<EOF
  2. [Unit]
  3. Description=Kubernetes API Server
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. [Service]
  6. EnvironmentFile=-/opt/kubernetes/config/kube-apiserver.conf
  7. ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
  8. Restart=on-failure
  9. RestartSec=10
  10. Type=notify
  11. LimitNOFILE=65536
  12. [Install]
  13. WantedBy=multi-user.target
  14. EOF

创建kube-controller-manager启动文件

  1. cat > /usr/lib/systemd/system/kube-controller-manager.service <<EOF
  2. [Unit]
  3. Description=Kubernetes Controller Manager
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. [Service]
  6. EnvironmentFile=-/opt/kubernetes/config/kube-controller-manager.conf
  7. ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
  8. Restart=on-failure
  9. [Install]
  10. WantedBy=multi-user.target
  11. EOF

创建kube-scheduler启动文件

  1. cat > /usr/lib/systemd/system/kube-scheduler.service <<EOF
  2. [Unit]
  3. Description=Kubernetes Scheduler
  4. Documentation=https://github.com/kubernetes/kubernetes
  5. [Service]
  6. EnvironmentFile=-/opt/kubernetes/config/kube-scheduler.conf
  7. ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
  8. Restart=on-failure
  9. [Install]
  10. WantedBy=multi-user.target
  11. EOF

创建kubelet启动文件

在需要部署的Node上创建

  1. cat > /usr/lib/systemd/system/kubelet.service <<EOF
  2. [Unit]
  3. Description=Kubernetes Kubelet
  4. After=docker.service
  5. Requires=docker.service
  6. [Service]
  7. EnvironmentFile=/opt/kubernetes/config/kubelet.conf
  8. ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
  9. Restart=on-failure
  10. KillMode=process
  11. [Install]
  12. WantedBy=multi-user.target
  13. EOF

创建kube-proxy启动文件

在需要部署的Node上创建

  1. cat > /usr/lib/systemd/system/kube-proxy.service <<EOF
  2. [Unit]
  3. Description=Kubernetes Proxy
  4. After=network.target
  5. [Service]
  6. EnvironmentFile=-/opt/kubernetes/config/kube-proxy.conf
  7. ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
  8. Restart=on-failure
  9. [Install]
  10. WantedBy=multi-user.target
  11. EOF

启动组件

master组件

由于我们master也准备当Node使用,所以我们将所有证书都拷贝到部署证书目录

  1. cp /root/kubernetes/ssl/kubernetes/*.pem /opt/kubernetes/ssl/

(1)、将我们创建的kubeconfig配置文件也拷贝到部署目录

  1. cp /root/kubernetes/kubeconfig/* /opt/kubernetes/config/

(2)、创建日志目录,并启动kube-apiserver

  1. mkdir /var/log/kubernetes
  2. systemctl daemon-reload && systemctl enable kube-apiserver && systemctl start kube-apiserver

(3)、复制kubeconfig文件到~/.kube/

  1. mv ~/.kube/config{,.old}
  2. cp /opt/kubernetes/config/admin.kubeconfig ~/.kube/config

(4)、查看状态

  1. systemctl status kube-apiserver
  2. # kubectl cluster-info
  3. Kubernetes master is running at https://10.1.10.128:6443

(5)、启动kube-controller-manager

  1. systemctl daemon-reload && systemctl enable kube-controller-manager && systemctl start kube-controller-manager

(6)、启动kube-scheduler

  1. systemctl daemon-reload && systemctl enable kube-scheduler && systemctl start kube-scheduler

(7)、查看集群状态

  1. # kubectl get cs -o=go-template='{{printf "|NAME|STATUS|MESSAGE|\n"}}{{range .items}}{{$name := .metadata.name}}{{range .conditions}}{{printf "|%s|%s|%s|\n" $name .status .message}}{{end}}{{end}}'
  2. |NAME|STATUS|MESSAGE|
  3. |scheduler|True|ok|
  4. |controller-manager|True|ok|
  5. |etcd-2|True|{"health":"true"}|
  6. |etcd-0|True|{"health":"true"}|
  7. |etcd-1|True|{"health":"true"}|
  8. # kubectl get all --all-namespaces
  9. NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  10. default service/kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 8m26s

(8)、授权访问kube-apiserver

  1. 授予 kubernetes API 的权限
  2. kubectl create clusterrolebinding controller-node-clusterrolebing --clusterrole=system:kube-controller-manager --user=system:kube-controller-manager
  3. kubectl create clusterrolebinding scheduler-node-clusterrolebing --clusterrole=system:kube-scheduler --user=system:kube-scheduler
  4. kubectl create clusterrolebinding controller-manager:system:auth-delegator --user system:kube-controller-manager --clusterrole system:auth-delegator
  5. 授予 kubernetes 证书访问 kubelet API 的权限
  6. kubectl create clusterrolebinding --user system:serviceaccount:kube-system:default kube-system-cluster-admin --clusterrole cluster-admin
  7. kubectl create clusterrolebinding kubelet-node-clusterbinding --clusterrole=system:node --group=system:nodes
  8. kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes

(9)、配置kubectl自动补全

  1. yum install -y bash-completion
  2. source /usr/share/bash-completion/bash_completion
  3. source <(kubectl completion bash)
  4. echo "source <(kubectl completion bash)" >> ~/.bashrc

如果要更改默认得namespace,可以使用如下命令

  1. kubectl config set-context --current --namespace={{namespace}}

node组件

在master上部署bootstrap secret,脚本可以放置任意位置,我习惯放于/root/manifests下。另外TOKEN_ID和TOKEN_SECRET是我们在创建bootstrap kubeconfig生成的,在做那一步的时候以防万一应该记录下来。

  1. cat << EOF | tee bootstrap.secret.yaml
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. # Name MUST be of form "bootstrap-token-<token id>"
  6. name: bootstrap-token-${TOKEN_ID}
  7. namespace: kube-system
  8. # Type MUST be 'bootstrap.kubernetes.io/token'
  9. type: bootstrap.kubernetes.io/token
  10. stringData:
  11. # Human readable description. Optional.
  12. description: "The default bootstrap token generated by 'kubelet '."
  13. # Token ID and secret. Required.
  14. token-id: ${TOKEN_ID}
  15. token-secret: ${TOKEN_SECRET}
  16. # Allowed usages.
  17. usage-bootstrap-authentication: "true"
  18. usage-bootstrap-signing: "true"
  19. # Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
  20. auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
  21. ---
  22. # A ClusterRole which instructs the CSR approver to approve a node requesting a
  23. # serving cert matching its client cert.
  24. kind: ClusterRole
  25. apiVersion: rbac.authorization.k8s.io/v1
  26. metadata:
  27. name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
  28. rules:
  29. - apiGroups: ["certificates.k8s.io"]
  30. resources: ["certificatesigningrequests/selfnodeserver"]
  31. verbs: ["create"]
  32. ---
  33. apiVersion: rbac.authorization.k8s.io/v1
  34. kind: ClusterRole
  35. metadata:
  36. annotations:
  37. rbac.authorization.kubernetes.io/autoupdate: "true"
  38. labels:
  39. kubernetes.io/bootstrapping: rbac-defaults
  40. name: system:kubernetes-to-kubelet
  41. rules:
  42. - apiGroups:
  43. - ""
  44. resources:
  45. - nodes/proxy
  46. - nodes/stats
  47. - nodes/log
  48. - nodes/spec
  49. - nodes/metrics
  50. verbs:
  51. - "*"
  52. ---
  53. apiVersion: rbac.authorization.k8s.io/v1
  54. kind: ClusterRoleBinding
  55. metadata:
  56. name: system:kubernetes
  57. namespace: ""
  58. roleRef:
  59. apiGroup: rbac.authorization.k8s.io
  60. kind: ClusterRole
  61. name: system:kubernetes-to-kubelet
  62. subjects:
  63. - apiGroup: rbac.authorization.k8s.io
  64. kind: User
  65. name: kubernetes
  66. EOF

然后创建资源

  1. # 创建资源
  2. kubectl create -f bootstrap.secret.yaml
  3. ### 查看创建的token
  4. kubeadm token list
  5. # 允许 system:bootstrappers 组用户创建 CSR 请求
  6. kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers
  7. # 自动批准 system:bootstrappers 组用户 TLS bootstrapping 首次申请证书的 CSR 请求
  8. kubectl create clusterrolebinding node-client-auto-approve-csr --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient --group=system:bootstrappers
  9. # 自动批准 system:nodes 组用户更新 kubelet 自身与 apiserver 通讯证书的 CSR 请求
  10. kubectl create clusterrolebinding node-client-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --group=system:nodes
  11. # 自动批准 system:nodes 组用户更新 kubelet 10250 api 端口证书的 CSR 请求
  12. kubectl create clusterrolebinding node-server-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeserver --group=system:nodes

(1)、在Node节点创建我们需要的目录

  1. mkdir /opt/kubernetes/{bin,config,ssl} -p

(2)、将node节点需要的二进制文件拷贝过去

  1. cd /root/kubernetes/install/kubernetes/server/bin
  2. scp kubelet kube-proxy 10.1.10.129:/opt/kubernetes/bin/
  3. scp kubelet kube-proxy 10.1.10.130:/opt/kubernetes/bin/

(3)、将kubeconfig文件拷贝到Node节点上

  1. cd /root/kubernetes/kubeconfig
  2. scp * 10.1.10.129:/opt/kubernetes/config/
  3. scp * 10.1.10.130:/opt/kubernetes/config/

(4)、将证书拷贝到Node节点上

只拷贝需要的,我这里仅仅是为了方便~~

  1. cd /root/kubernetes/ssl/kubernetes
  2. scp *.pem 10.1.10.129:/opt/kubernetes/ssl/
  3. scp *.pem 10.1.10.130:/opt/kubernetes/ssl/

(5)、启动kubelet

  1. systemctl daemon-reload && systemctl enable kubelet && systemctl start kubelet

(6)、启动kube-proxy

  1. systemctl daemon-reload && systemctl enable kube-proxy && systemctl start kube-proxy

(7)、在master上查看

  1. kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. node01-k8s NotReady <none> 72m v1.16.4
  4. node02-k8s NotReady <none> 5m12s v1.16.4

之所以是NotReady,是因为我们还没有部署网络

安装组件

部署Flannel

kubernetes提供一个CNI接口,它可以和任何支持CNI的网络插件对接,所以我们这里不直接部署Flannel,改成部署cni,然后将flannel部署在集群中。

使用CNI插件时,需要做三个配置:

  • kubelet启动参数中networkPlugin设置为cni
  • 在/etc/cni/net.d中增加cni的配置文件,配置文件中可以指定需要使用的cni组件及参数
  • 将需要用到的cni组件(二进制可执行文件)放到/opt/cni/bin目录下

(1)、确保配置中开启了cni,如下

  1. KUBELET_OPTS="--logtostderr=true \
  2. --v=4 \
  3. --network-plugin=cni \
  4. --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin \
  5. --hostname-override=10.1.10.128 \
  6. --kubeconfig=/opt/kubernetes/config/kubelet.kubeconfig \
  7. --bootstrap-kubeconfig=/opt/kubernetes/config/bootstrap.kubeconfig \
  8. --config=/opt/kubernetes/config/kubelet.config \
  9. --cert-dir=/opt/kubernetes/ssl \
  10. --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/rookieops/pause-amd64:3.0"

(2)、下载cni文件

下载地址:https://github.com/containernetworking/plugins/releases/download/v0.8.3/cni-plugins-linux-amd64-v0.8.3.tgz

(3)、创建需要的目录

  1. mkdir /opt/cni/bin /etc/cni/net.d -p

(4)、解压压缩包到安装目录/opt/cni/bin

  1. tar xf cni-plugins-linux-amd64-v0.8.3.tgz -C /opt/cni/bin/

(5)、将其拷贝到另外的节点

  1. scp -r /opt/cni/bin/* 10.1.10.129:/opt/cni/bin/
  2. scp -r /opt/cni/bin/* 10.1.10.130:/opt/cni/bin/

(6)、配置kube-flannel YAML清单文件(kube-flannel.yaml)

下载地址:https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

  1. ---
  2. apiVersion: policy/v1beta1
  3. kind: PodSecurityPolicy
  4. metadata:
  5. name: psp.flannel.unprivileged
  6. annotations:
  7. seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
  8. seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
  9. apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
  10. apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
  11. spec:
  12. privileged: false
  13. volumes:
  14. - configMap
  15. - secret
  16. - emptyDir
  17. - hostPath
  18. allowedHostPaths:
  19. - pathPrefix: "/etc/cni/net.d"
  20. - pathPrefix: "/etc/kube-flannel"
  21. - pathPrefix: "/run/flannel"
  22. readOnlyRootFilesystem: false
  23. # Users and groups
  24. runAsUser:
  25. rule: RunAsAny
  26. supplementalGroups:
  27. rule: RunAsAny
  28. fsGroup:
  29. rule: RunAsAny
  30. # Privilege Escalation
  31. allowPrivilegeEscalation: false
  32. defaultAllowPrivilegeEscalation: false
  33. # Capabilities
  34. allowedCapabilities: ['NET_ADMIN']
  35. defaultAddCapabilities: []
  36. requiredDropCapabilities: []
  37. # Host namespaces
  38. hostPID: false
  39. hostIPC: false
  40. hostNetwork: true
  41. hostPorts:
  42. - min: 0
  43. max: 65535
  44. # SELinux
  45. seLinux:
  46. # SELinux is unsed in CaaSP
  47. rule: 'RunAsAny'
  48. ---
  49. kind: ClusterRole
  50. apiVersion: rbac.authorization.k8s.io/v1beta1
  51. metadata:
  52. name: flannel
  53. rules:
  54. - apiGroups: ['extensions']
  55. resources: ['podsecuritypolicies']
  56. verbs: ['use']
  57. resourceNames: ['psp.flannel.unprivileged']
  58. - apiGroups:
  59. - ""
  60. resources:
  61. - pods
  62. verbs:
  63. - get
  64. - apiGroups:
  65. - ""
  66. resources:
  67. - nodes
  68. verbs:
  69. - list
  70. - watch
  71. - apiGroups:
  72. - ""
  73. resources:
  74. - nodes/status
  75. verbs:
  76. - patch
  77. ---
  78. kind: ClusterRoleBinding
  79. apiVersion: rbac.authorization.k8s.io/v1beta1
  80. metadata:
  81. name: flannel
  82. roleRef:
  83. apiGroup: rbac.authorization.k8s.io
  84. kind: ClusterRole
  85. name: flannel
  86. subjects:
  87. - kind: ServiceAccount
  88. name: flannel
  89. namespace: kube-system
  90. ---
  91. apiVersion: v1
  92. kind: ServiceAccount
  93. metadata:
  94. name: flannel
  95. namespace: kube-system
  96. ---
  97. kind: ConfigMap
  98. apiVersion: v1
  99. metadata:
  100. name: kube-flannel-cfg
  101. namespace: kube-system
  102. labels:
  103. tier: node
  104. app: flannel
  105. data:
  106. cni-conf.json: |
  107. {
  108. "cniVersion": "0.2.0",
  109. "name": "cbr0",
  110. "plugins": [
  111. {
  112. "type": "flannel",
  113. "delegate": {
  114. "hairpinMode": true,
  115. "isDefaultGateway": true
  116. }
  117. },
  118. {
  119. "type": "portmap",
  120. "capabilities": {
  121. "portMappings": true
  122. }
  123. }
  124. ]
  125. }
  126. net-conf.json: |
  127. {
  128. "Network": "172.20.0.0/16",
  129. "Backend": {
  130. "Type": "vxlan"
  131. }
  132. }
  133. ---
  134. apiVersion: apps/v1
  135. kind: DaemonSet
  136. metadata:
  137. name: kube-flannel-ds-amd64
  138. namespace: kube-system
  139. labels:
  140. tier: node
  141. app: flannel
  142. spec:
  143. selector:
  144. matchLabels:
  145. app: flannel
  146. template:
  147. metadata:
  148. labels:
  149. tier: node
  150. app: flannel
  151. spec:
  152. affinity:
  153. nodeAffinity:
  154. requiredDuringSchedulingIgnoredDuringExecution:
  155. nodeSelectorTerms:
  156. - matchExpressions:
  157. - key: beta.kubernetes.io/os
  158. operator: In
  159. values:
  160. - linux
  161. - key: beta.kubernetes.io/arch
  162. operator: In
  163. values:
  164. - amd64
  165. hostNetwork: true
  166. tolerations:
  167. - operator: Exists
  168. effect: NoSchedule
  169. serviceAccountName: flannel
  170. initContainers:
  171. - name: install-cni
  172. image: registry.cn-hangzhou.aliyuncs.com/rookieops/flannel:v0.11.0-amd64
  173. command:
  174. - cp
  175. args:
  176. - -f
  177. - /etc/kube-flannel/cni-conf.json
  178. - /etc/cni/net.d/10-flannel.conflist
  179. volumeMounts:
  180. - name: cni
  181. mountPath: /etc/cni/net.d
  182. - name: flannel-cfg
  183. mountPath: /etc/kube-flannel/
  184. containers:
  185. - name: kube-flannel
  186. image: registry.cn-hangzhou.aliyuncs.com/rookieops/flannel:v0.11.0-amd64
  187. command:
  188. - /opt/bin/flanneld
  189. args:
  190. - --ip-masq
  191. - --kube-subnet-mgr
  192. resources:
  193. requests:
  194. cpu: "100m"
  195. memory: "50Mi"
  196. limits:
  197. cpu: "100m"
  198. memory: "50Mi"
  199. securityContext:
  200. privileged: false
  201. capabilities:
  202. add: ["NET_ADMIN"]
  203. env:
  204. - name: POD_NAME
  205. valueFrom:
  206. fieldRef:
  207. fieldPath: metadata.name
  208. - name: POD_NAMESPACE
  209. valueFrom:
  210. fieldRef:
  211. fieldPath: metadata.namespace
  212. volumeMounts:
  213. - name: run
  214. mountPath: /run/flannel
  215. - name: flannel-cfg
  216. mountPath: /etc/kube-flannel/
  217. volumes:
  218. - name: run
  219. hostPath:
  220. path: /run/flannel
  221. - name: cni
  222. hostPath:
  223. path: /etc/cni/net.d
  224. - name: flannel-cfg
  225. configMap:
  226. name: kube-flannel-cfg

(7)、生成资源清单

  1. kubectl apply -f kube-flannel.yaml

(8)、查看集群状态

  1. # kubectl get pod -n kube-system
  2. NAME READY STATUS RESTARTS AGE
  3. kube-flannel-ds-amd64-2qkcb 1/1 Running 0 85s
  4. kube-flannel-ds-amd64-7nzj5 1/1 Running 0 85s
  5. # kubectl get node
  6. NAME STATUS ROLES AGE VERSION
  7. node01-k8s Ready <none> 104m v1.16.4
  8. node02-k8s Ready <none> 37m v1.16.4

可以看到集群状态已经变为ready

(9)、用一个demo文件测试一下

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pod-demo
  5. spec:
  6. containers:
  7. - name: test-ng
  8. image: nginx

查看是否能成功分配IP

  1. # kubectl get pod -o wide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. kube-flannel-ds-amd64-2qkcb 1/1 Running 0 5m36s 10.1.10.129 node01-k8s <none> <none>
  4. kube-flannel-ds-amd64-7nzj5 1/1 Running 0 5m36s 10.1.10.130 node02-k8s <none> <none>
  5. pod-demo 1/1 Running 0 55s 172.20.1.2 node02-k8s <none> <none>

测试正常

部署core dns

YAML清单如下

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: coredns
  5. namespace: kube-system
  6. labels:
  7. kubernetes.io/cluster-service: "true"
  8. addonmanager.kubernetes.io/mode: Reconcile
  9. ---
  10. apiVersion: rbac.authorization.k8s.io/v1
  11. kind: ClusterRole
  12. metadata:
  13. labels:
  14. kubernetes.io/bootstrapping: rbac-defaults
  15. addonmanager.kubernetes.io/mode: Reconcile
  16. name: system:coredns
  17. rules:
  18. - apiGroups:
  19. - ""
  20. resources:
  21. - endpoints
  22. - services
  23. - pods
  24. - namespaces
  25. verbs:
  26. - list
  27. - watch
  28. - apiGroups:
  29. - ""
  30. resources:
  31. - nodes
  32. verbs:
  33. - get
  34. ---
  35. apiVersion: rbac.authorization.k8s.io/v1
  36. kind: ClusterRoleBinding
  37. metadata:
  38. annotations:
  39. rbac.authorization.kubernetes.io/autoupdate: "true"
  40. labels:
  41. kubernetes.io/bootstrapping: rbac-defaults
  42. addonmanager.kubernetes.io/mode: EnsureExists
  43. name: system:coredns
  44. roleRef:
  45. apiGroup: rbac.authorization.k8s.io
  46. kind: ClusterRole
  47. name: system:coredns
  48. subjects:
  49. - kind: ServiceAccount
  50. name: coredns
  51. namespace: kube-system
  52. ---
  53. apiVersion: v1
  54. kind: ConfigMap
  55. metadata:
  56. name: coredns
  57. namespace: kube-system
  58. labels:
  59. addonmanager.kubernetes.io/mode: EnsureExists
  60. data:
  61. Corefile: |
  62. .:53 {
  63. errors
  64. health
  65. kubernetes cluster.local in-addr.arpa ip6.arpa {
  66. pods insecure
  67. upstream /etc/resolv.conf
  68. fallthrough in-addr.arpa ip6.arpa
  69. }
  70. prometheus :9153
  71. forward . /etc/resolv.conf
  72. cache 30
  73. reload
  74. loadbalance
  75. }
  76. ---
  77. apiVersion: apps/v1
  78. kind: Deployment
  79. metadata:
  80. name: coredns
  81. namespace: kube-system
  82. labels:
  83. k8s-app: kube-dns
  84. kubernetes.io/cluster-service: "true"
  85. addonmanager.kubernetes.io/mode: Reconcile
  86. kubernetes.io/name: "CoreDNS"
  87. spec:
  88. # replicas: not specified here:
  89. # 1. In order to make Addon Manager do not reconcile this replicas parameter.
  90. # 2. Default is 1.
  91. # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
  92. strategy:
  93. type: RollingUpdate
  94. rollingUpdate:
  95. maxUnavailable: 1
  96. selector:
  97. matchLabels:
  98. k8s-app: kube-dns
  99. template:
  100. metadata:
  101. labels:
  102. k8s-app: kube-dns
  103. annotations:
  104. seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
  105. spec:
  106. priorityClassName: system-cluster-critical
  107. serviceAccountName: coredns
  108. tolerations:
  109. - key: "CriticalAddonsOnly"
  110. operator: "Exists"
  111. nodeSelector:
  112. beta.kubernetes.io/os: linux
  113. containers:
  114. - name: coredns
  115. image: coredns/coredns
  116. imagePullPolicy: Always
  117. resources:
  118. limits:
  119. memory: 170Mi
  120. requests:
  121. cpu: 100m
  122. memory: 70Mi
  123. args: [ "-conf", "/etc/coredns/Corefile" ]
  124. volumeMounts:
  125. - name: config-volume
  126. mountPath: /etc/coredns
  127. readOnly: true
  128. ports:
  129. - containerPort: 53
  130. name: dns
  131. protocol: UDP
  132. - containerPort: 53
  133. name: dns-tcp
  134. protocol: TCP
  135. - containerPort: 9153
  136. name: metrics
  137. protocol: TCP
  138. livenessProbe:
  139. httpGet:
  140. path: /health
  141. port: 8080
  142. scheme: HTTP
  143. initialDelaySeconds: 60
  144. timeoutSeconds: 5
  145. successThreshold: 1
  146. failureThreshold: 5
  147. readinessProbe:
  148. httpGet:
  149. path: /health
  150. port: 8080
  151. scheme: HTTP
  152. securityContext:
  153. allowPrivilegeEscalation: false
  154. capabilities:
  155. add:
  156. - NET_BIND_SERVICE
  157. drop:
  158. - all
  159. readOnlyRootFilesystem: true
  160. dnsPolicy: Default
  161. volumes:
  162. - name: config-volume
  163. configMap:
  164. name: coredns
  165. items:
  166. - key: Corefile
  167. path: Corefile
  168. ---
  169. apiVersion: v1
  170. kind: Service
  171. metadata:
  172. name: kube-dns
  173. namespace: kube-system
  174. annotations:
  175. prometheus.io/port: "9153"
  176. prometheus.io/scrape: "true"
  177. labels:
  178. k8s-app: kube-dns
  179. kubernetes.io/cluster-service: "true"
  180. addonmanager.kubernetes.io/mode: Reconcile
  181. kubernetes.io/name: "CoreDNS"
  182. spec:
  183. selector:
  184. k8s-app: kube-dns
  185. clusterIP: 10.254.0.2
  186. ports:
  187. - name: dns
  188. port: 53
  189. protocol: UDP
  190. - name: dns-tcp
  191. port: 53
  192. protocol: TCP
  193. - name: metrics
  194. port: 9153
  195. protocol: TCP

测试:

  1. # 安装测试攻击
  2. yum install bind-utils-y
  3. # 测试百度,要在Node节点测试,因为我们master没有安装网络
  4. # dig @10.254.0.2 www.baidu.com
  5. ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> @10.254.0.2 www.baidu.com
  6. ; (1 server found)
  7. ;; global options: +cmd
  8. ;; Got answer:
  9. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24278
  10. ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
  11. ;; OPT PSEUDOSECTION:
  12. ; EDNS: version: 0, flags:; udp: 4096
  13. ;; QUESTION SECTION:
  14. ;www.baidu.com. IN A
  15. ;; ANSWER SECTION:
  16. www.baidu.com. 30 IN CNAME www.a.shifen.com.
  17. www.a.shifen.com. 30 IN A 112.80.248.75
  18. www.a.shifen.com. 30 IN A 112.80.248.76
  19. ;; Query time: 54 msec
  20. ;; SERVER: 10.254.0.2#53(10.254.0.2)
  21. ;; WHEN: Sat Dec 28 23:40:43 CST 2019
  22. ;; MSG SIZE rcvd: 149

返回解析正常

部署Traefik Ingress

(1)、创建RBAC认证配置清单(traefik-rbac.yaml)

  1. ---
  2. apiVersion: v1
  3. kind: ServiceAccount
  4. metadata:
  5. name: traefik-ingress-controller
  6. namespace: kube-system
  7. ---
  8. kind: ClusterRole
  9. apiVersion: rbac.authorization.k8s.io/v1beta1
  10. metadata:
  11. name: traefik-ingress-controller
  12. rules:
  13. - apiGroups:
  14. - ""
  15. resources:
  16. - services
  17. - endpoints
  18. - secrets
  19. verbs:
  20. - get
  21. - list
  22. - watch
  23. - apiGroups:
  24. - extensions
  25. resources:
  26. - ingresses
  27. verbs:
  28. - get
  29. - list
  30. - watch
  31. ---
  32. kind: ClusterRoleBinding
  33. apiVersion: rbac.authorization.k8s.io/v1beta1
  34. metadata:
  35. name: traefik-ingress-controller
  36. roleRef:
  37. apiGroup: rbac.authorization.k8s.io
  38. kind: ClusterRole
  39. name: traefik-ingress-controller
  40. subjects:
  41. - kind: ServiceAccount
  42. name: traefik-ingress-controller
  43. namespace: kube-system

(2)、创建traefik配置清单(traefik.yaml)

  1. ---
  2. kind: Deployment
  3. apiVersion: apps/v1
  4. metadata:
  5. name: traefik-ingress-controller
  6. namespace: kube-system
  7. labels:
  8. k8s-app: traefik-ingress-lb
  9. spec:
  10. replicas: 1
  11. selector:
  12. matchLabels:
  13. k8s-app: traefik-ingress-lb
  14. template:
  15. metadata:
  16. labels:
  17. k8s-app: traefik-ingress-lb
  18. name: traefik-ingress-lb
  19. spec:
  20. serviceAccountName: traefik-ingress-controller
  21. terminationGracePeriodSeconds: 60
  22. # tolerations:
  23. # - operator: "Exists"
  24. # nodeSelector:
  25. # kubernetes.io/hostname: master
  26. containers:
  27. - image: traefik:v1.7.17
  28. name: traefik-ingress-lb
  29. ports:
  30. - name: http
  31. containerPort: 80
  32. - name: admin
  33. containerPort: 8080
  34. args:
  35. - --api
  36. - --kubernetes
  37. - --logLevel=INFO
  38. ---
  39. kind: Service
  40. apiVersion: v1
  41. metadata:
  42. name: traefik-ingress-service
  43. namespace: kube-system
  44. spec:
  45. selector:
  46. k8s-app: traefik-ingress-lb
  47. ports:
  48. - protocol: TCP
  49. port: 80
  50. name: web
  51. nodePort: 38000
  52. - protocol: TCP
  53. port: 8080
  54. nodePort: 38080
  55. name: admin
  56. type: NodePort

(3)、创建配置清单

  1. kubectl apply -f traefik-rbac.yaml
  2. kubectl apply -g traefik.yaml

(4)、查看结果

  1. kubectl get pod -n kube-system
  2. NAME READY STATUS RESTARTS AGE
  3. coredns-9d5b6bdb6-mpwht 1/1 Running 0 22h
  4. kube-flannel-ds-amd64-2qkcb 1/1 Running 0 22h
  5. kube-flannel-ds-amd64-7nzj5 1/1 Running 0 22h
  6. pod-demo 1/1 Running 0 22h
  7. traefik-ingress-controller-7758594f89-lwf2t 1/1 Running 0 41s
  8. # kubectl get svc -n kube-system
  9. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  10. kube-dns ClusterIP 10.254.0.2 <none> 53/UDP,53/TCP,9153/TCP 22h
  11. traefik-ingress-service NodePort 10.254.33.90 <none> 80:38000/TCP,8080:38080/TCP 3m33s

我们可以通过http://10.1.10.129:38080 来查看Dashboard,如下

部署Dashboard

(1)、部署,直接是官方部署文档

  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

(2)、配置Ingress或者将service类型改为NodePort,我这里改为NodePort

  1. kubectl edit svc -n kubernetes-dashboard kubernetes-dashboard

(3)、然后我们在浏览器访问

  1. # kubectl get svc -n kubernetes-dashboard
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. dashboard-metrics-scraper ClusterIP 10.254.224.240 <none> 8000/TCP 2m28s
  4. kubernetes-dashboard NodePort 10.254.82.50 <none> 443:28330/TCP 2m28s

(4)、创建一个admin token

  1. # 创建sa
  2. kubectl create sa dashboard-admin -n kube-system
  3. # 授权
  4. kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
  5. # 获取token
  6. ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')
  7. # 获取dashboard kubeconfig使用token的值
  8. DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}')
  9. echo ${DASHBOARD_LOGIN_TOKEN}

(5)、创建dashboard kubeconfig

还是在我们统一的Kubeconfig目录下创建/root/kubernetes/kubeconfig

  1. # 设置集群参数
  2. kubectl config set-cluster kubernetes \
  3. --certificate-authority=../ssl/kubernetes/ca.pem \
  4. --embed-certs=true \
  5. --server=${KUBE_APISERVER} \
  6. --kubeconfig=dashboard.kubeconfig
  7. # 设置客户端认证参数,使用上面创建的 Token
  8. kubectl config set-credentials dashboard_user \
  9. --token=${DASHBOARD_LOGIN_TOKEN} \
  10. --kubeconfig=dashboard.kubeconfig
  11. # 设置上下文参数
  12. kubectl config set-context default \
  13. --cluster=kubernetes \
  14. --user=dashboard_user \
  15. --kubeconfig=dashboard.kubeconfig
  16. # 设置默认上下文
  17. kubectl config use-context default --kubeconfig=dashboard.kubeconfig

然后下载dashboard.kubeconfig,在登录的时候上传即可进入主界面,如下
image.png

部署Metrics Server

github:https://github.com/kubernetes-sigs/metrics-server 稳定版:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/metrics-server

(1)、下载YAML清单

  1. for file in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml;do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/metrics-server/${file}; done

(2)、修改metrics-server-deployment.yaml配置清单,如下

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: metrics-server
  5. namespace: kube-system
  6. labels:
  7. kubernetes.io/cluster-service: "true"
  8. addonmanager.kubernetes.io/mode: Reconcile
  9. ---
  10. apiVersion: v1
  11. kind: ConfigMap
  12. metadata:
  13. name: metrics-server-config
  14. namespace: kube-system
  15. labels:
  16. kubernetes.io/cluster-service: "true"
  17. addonmanager.kubernetes.io/mode: EnsureExists
  18. data:
  19. NannyConfiguration: |-
  20. apiVersion: nannyconfig/v1alpha1
  21. kind: NannyConfiguration
  22. ---
  23. apiVersion: apps/v1
  24. kind: Deployment
  25. metadata:
  26. name: metrics-server-v0.3.6
  27. namespace: kube-system
  28. labels:
  29. k8s-app: metrics-server
  30. kubernetes.io/cluster-service: "true"
  31. addonmanager.kubernetes.io/mode: Reconcile
  32. version: v0.3.6
  33. spec:
  34. selector:
  35. matchLabels:
  36. k8s-app: metrics-server
  37. version: v0.3.6
  38. template:
  39. metadata:
  40. name: metrics-server
  41. labels:
  42. k8s-app: metrics-server
  43. version: v0.3.6
  44. annotations:
  45. seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
  46. spec:
  47. priorityClassName: system-cluster-critical
  48. serviceAccountName: metrics-server
  49. nodeSelector:
  50. kubernetes.io/os: linux
  51. containers:
  52. - name: metrics-server
  53. image: registry.cn-hangzhou.aliyuncs.com/rookieops/metrics-server-amd64:v0.3.6
  54. command:
  55. - /metrics-server
  56. - --metric-resolution=30s
  57. - --kubelet-insecure-tls
  58. # These are needed for GKE, which doesn't support secure communication yet.
  59. # Remove these lines for non-GKE clusters, and when GKE supports token-based auth.
  60. # - --deprecated-kubelet-completely-insecure=true
  61. - --kubelet-port=10250
  62. - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
  63. ports:
  64. - containerPort: 443
  65. name: https
  66. protocol: TCP
  67. - name: metrics-server-nanny
  68. image: registry.cn-hangzhou.aliyuncs.com/rookieops/addon-resizer:1.8.6
  69. resources:
  70. limits:
  71. cpu: 100m
  72. memory: 300Mi
  73. requests:
  74. cpu: 100m
  75. memory: 300Mi
  76. env:
  77. - name: MY_POD_NAME
  78. valueFrom:
  79. fieldRef:
  80. fieldPath: metadata.name
  81. - name: MY_POD_NAMESPACE
  82. valueFrom:
  83. fieldRef:
  84. fieldPath: metadata.namespace
  85. volumeMounts:
  86. - name: metrics-server-config-volume
  87. mountPath: /etc/config
  88. command:
  89. - /pod_nanny
  90. - --config-dir=/etc/config
  91. - --cpu=100m
  92. - --extra-cpu=0.5m
  93. - --memory=100Mi
  94. - --extra-memory=50Mi
  95. - --threshold=5
  96. - --deployment=metrics-server-v0.3.6
  97. - --container=metrics-server
  98. - --poll-period=300000
  99. - --estimator=exponential
  100. # Specifies the smallest cluster (defined in number of nodes)
  101. # resources will be scaled to.
  102. # - --minClusterSize=2
  103. volumes:
  104. - name: metrics-server-config-volume
  105. configMap:
  106. name: metrics-server-config

(3)、修改resource-reader.yaml如下

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: system:metrics-server
  5. labels:
  6. kubernetes.io/cluster-service: "true"
  7. addonmanager.kubernetes.io/mode: Reconcile
  8. rules:
  9. - apiGroups:
  10. - ""
  11. resources:
  12. - pods
  13. - nodes
  14. - namespaces
  15. - nodes/stats
  16. verbs:
  17. - get
  18. - list
  19. - watch
  20. - apiGroups:
  21. - "apps"
  22. resources:
  23. - deployments
  24. verbs:
  25. - get
  26. - list
  27. - update
  28. - watch
  29. - apiGroups:
  30. - "extensions"
  31. resources:
  32. - deployments
  33. verbs:
  34. - get
  35. - list
  36. - update
  37. - watch
  38. ---
  39. apiVersion: rbac.authorization.k8s.io/v1
  40. kind: ClusterRoleBinding
  41. metadata:
  42. name: system:metrics-server
  43. labels:
  44. kubernetes.io/cluster-service: "true"
  45. addonmanager.kubernetes.io/mode: Reconcile
  46. roleRef:
  47. apiGroup: rbac.authorization.k8s.io
  48. kind: ClusterRole
  49. name: system:metrics-server
  50. subjects:
  51. - kind: ServiceAccount
  52. name: metrics-server
  53. namespace: kube-system

(4)、然后创建 配置清单

  1. for file in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml;do kubectl apply -f ${file};done

(5)、查看

  1. # kubectl top node
  2. NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
  3. master-k8s 195m 19% 1147Mi 66%
  4. node01-k8s 117m 11% 885Mi 51%
  5. node02-k8s 117m 11% 945Mi 54%

如果出现error: metrics not available yet,重启kubelet(至少我是这样)

image.png

参考文档 作者:juestnow 地址:https://blog.51cto.com/juestnow/2439614 作者:余温竹下侯 地址:https://note.youdao.com/ynoteshare1/index.html?id=62351b1d4c803f7c6f180368b75fd3bf&type=note