时至而生 – 唯变长存

Kubernetes 1.13.6 集群二进制文件部署(单Master)

2019-05-14
20次浏览

部署节点说明

IP地址          主机名         配置
192.168.0.3     k8s-master     2/4G
192.168.0.4     k8s-node1      2/4G
192.168.0.5     k8s-node2      2/4G

软件版本:CentOS 7.6、Kubernetes 1.13.6、Docker 18.09.6

注:下文会以中括号+斜体字 [简写主机名] 的形式标注所在节点的操作,[all] 代表所有节点。

一、初始化环境

1.1 配置主机名 [all]

hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2

1.2 修改 hosts 文件 [all]

vim /etc/hosts

# 追加如下
192.168.0.3 k8s-master
192.168.0.4 k8s-node1
192.168.0.5 k8s-node2

1.3 建立所有节点的 ssh-key 认证 [master]

ssh-keygen
ssh-copy-id 192.168.0.4
ssh-copy-id 192.168.0.5

1.4 关闭防火墙和 SELinux [all]

systemctl disable firewalld && systemctl stop firewalld
setenforce 0
sed -i 's/^SELINUX=.*$/SELINUX=disabled/g' /etc/selinux/config

1.5 关闭 Swap [all]

swapoff -a && sysctl -w vm.swappiness=0
vim /etc/fstab

# 注释下面这一行
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

1.5 设置 Docker 所需参数 [all]

cat << EOF | tee /etc/sysctl.d/docker.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl -p /etc/sysctl.d/docker.conf

1.6 安装 Docker [all]

# 更新系统
yum update -y

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce

systemctl start docker && systemctl enable docker

1.7 创建安装目录 [all]

创建 kubernetes 主目录,用于存放有关文件:

mkdir -p /opt/kubernetes/{bin,cfg,ssl} && mkdir /var/lib/etcd
vim /etc/profile

#Kubernetes
export PATH=$PATH:/opt/kubernetes/bin
source /etc/profile

二、安装及配置 CFSSL [master]

自签 TLS 证书,下载地址:http://pkg.cfssl.org/

2.1 下载安装 CFSSL

wget http://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget http://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget http://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 cfssl
mv cfssl-certinfo_linux-amd64 cfssl-certinfo
mv cfssljson_linux-amd64 cfssljson
chmod +x cfssl* && mv cfssl* /usr/local/bin/

创建一个临时存储文件的目录:

mkdir ssl && cd ssl

2.2 创建 CA 配置文件

cat << EOF | tee ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF
  • ca-config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile
  • signing:表示该证书可用于签名其它证书;生成的ca.pem证书中CA=TRUE
  • server auth:表示 client 可以用该 CA 对 server 提供的证书进行验证;
  • client auth:表示 server 可以用该 CA 对 client 提供的证书进行验证。

2.3 创建 CA 证书签名请求

cat << EOF | tee ca-csr.json
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Nanjing",
            "ST": "Nanjing",
              "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
  • "CN":Common Name,kube-apiserver从证书中提取该字段作为请求的用户名(User Name);浏览器使用该字段验证网站是否合法;
  • "O":Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组(Group)

生成 CA 证书和私钥:

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

2.4 创建 kubernetes 证书签名请求文件

集群节点预加载IP都要写全:

cat << EOF | tee server-csr.json
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "192.168.0.3",
      "192.168.0.4",
      "192.168.0.5",
      "192.168.0.6",
      "10.10.10.1",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "NanJing",
            "ST": "NanJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

hosts中的内容可以为空,即使按照上面的配置,向集群中增加新节点后也不需要重新生成证书。

如果hosts字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群、kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP

生成 kubernetes 证书和私钥:

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

2.5 创建 admin 证书

cat << EOF | tee admin-csr.json
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "NanJing",
      "ST": "NanJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;kube-apiserver 预定义了一些 RBAC 使用的RoleBindings,如cluster-adminGroup system:mastersRole cluster-admin绑定,该Role授予了调用 kube-apiserver 的所有 API 的权限;OU指定该证书的Groupsystem:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的system:masters,所以被授予访问所有 API 的权限。

生成 admin 证书和私钥:

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

2.6 创建 kube-proxy 证书

cat << EOF | tee kube-proxy-csr.json
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "Nanjing",
      "ST": "Nanjing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

CN指定该证书的Usersystem:kube-proxy;kube-apiserver 预定义的RoleBinding cluster-adminUser system:kube-proxyRole system:node-proxier绑定,该Role授予了调用kube-apiserver Proxy相关 API 的权限。

生成 kube-proxy 客户端证书和私钥:

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

2.7 分发证书和密钥

至此证书全部生成完毕!将生成的证书和密钥文件分发到所有机器的/opt/kubernetes/ssl目录下:

mv *.pem /opt/kubernetes/ssl
scp /opt/kubernetes/ssl/*.pem root@k8s-node1:/opt/kubernetes/ssl/
scp /opt/kubernetes/ssl/*.pem root@k8s-node2:/opt/kubernetes/ssl/

三、部署Etcd集群 [master]

etcd 是一个高可用的键值存储系统,主要用于共享配置和服务发现。etcd 是由 CoreOS 开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用 Go 语言编写,并通过 Raft 一致性算法处理日志复制以保证强一致性。下载地址:https://github.com/etcd-io/etcd/releases

下载安装

mkdir ~/src && cd ~/src
wget https://github.com/etcd-io/etcd/releases/download/v3.3.13/etcd-v3.3.13-linux-amd64.tar.gz
tar zxvf tar zxvf etcd-v3.3.13-linux-amd64.tar.gz
cp etcd-v3.3.13-linux-amd64/etcd* /opt/kubernetes/bin/

3.1 编辑配置文件

cat << EOF | tee /opt/kubernetes/cfg/etcd
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.0.3:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.0.3:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.0.3:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.0.3:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.0.3:2380,etcd02=https://192.168.0.4:2380,etcd03=https://192.168.0.5:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

3.2 创建 systemd unit 文件来管理 etcd

cat << EOF | tee /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/opt/kubernetes/cfg/etcd
ExecStart=/opt/kubernetes/bin/etcd \
--name=${ETCD_NAME} \
--data-dir=${ETCD_DATA_DIR} \
--listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
--listen-client-urls=${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \
--advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
--initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--initial-cluster=${ETCD_INITIAL_CLUSTER} \
--initial-cluster-token=${ETCD_INITIAL_CLUSTER} \
--initial-cluster-state=new \
--cert-file=/opt/kubernetes/ssl/server.pem \
--key-file=/opt/kubernetes/ssl/server-key.pem \
--peer-cert-file=/opt/kubernetes/ssl/server.pem \
--peer-key-file=/opt/kubernetes/ssl/server-key.pem \
--trusted-ca-file=/opt/kubernetes/ssl/ca.pem \
--peer-trusted-ca-file=/opt/kubernetes/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

配置参数解释:

  • --name:方便理解的节点名称,默认为default,在集群中应该保持唯一,可以使用hostname
  • --data-dir:服务运行数据保存的路径,默认为${name}.etcd
  • --snapshot-count:指定有多少事务(transaction)被提交时,触发截取快照保存到磁盘;
  • --heartbeat-intervalleader多久发送一次心跳到followers。默认值是100ms
  • --eletion-timeout:重新投票的超时时间,如果follow在该时间间隔没有收到心跳包,会触发重新投票,默认为1000 ms
  • --listen-peer-urls:和同伴通信的地址,比如http://ip:2380,如果有多个,使用逗号分隔。需要所有节点都能够访问,所以不要使用localhost
  • --listen-client-urls:对外提供服务的地址:比如http://ip:2379,http://127.0.0.1:2379,客户端会连接到这里和 etcd 交互;
  • --advertise-client-urls:对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点;
  • --initial-advertise-peer-urls:该节点同伴监听地址,这个值会告诉集群中其他节点;
  • --initial-cluster:集群中所有节点的信息,格式为node1=http://ip1:2380,node2=http://ip2:2380,…。注意:这里的 node1 是节点的--name指定的名字;后面的ip1:2380--initial-advertise-peer-urls指定的值;
  • --initial-cluster-state:新建集群的时候,这个值为new;假如已经存在的集群,这个值为existing
  • --initial-cluster-token:创建集群的token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点uuid;否则会导致多个集群之间的冲突,造成未知的错误;

3.3 分发文件到各节点

scp /opt/kubernetes/bin/etcd* root@192.168.0.4:/opt/kubernetes/bin/
scp /opt/kubernetes/bin/etcd* root@192.168.0.5:/opt/kubernetes/bin/

scp /opt/kubernetes/cfg/etcd root@192.168.0.4:/opt/kubernetes/cfg/
scp /opt/kubernetes/cfg/etcd root@192.168.0.5:/opt/kubernetes/cfg/

scp /opt/kubernetes/ssl/*.pem root@192.168.0.4:/opt/kubernetes/ssl/
scp /opt/kubernetes/ssl/*.pem root@192.168.0.5:/opt/kubernetes/ssl/

scp /usr/lib/systemd/system/etcd.service root@192.168.0.4:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@192.168.0.5:/usr/lib/systemd/system/

注:传输到 192.168.0.4、192.168.0.5 的配置文件需要修改 ip 等参数信息。

3.4 启动 etcd

systemctl start etcd && systemctl enable etcd
ssh root@192.168.0.4 "systemctl start etcd && systemctl enable etcd"
ssh root@192.168.0.5 "systemctl start etcd && systemctl enable etcd"

如果 node 结点没有启动,master 节点此时启动后会卡主一段时间(要按ctrl+c才行),需要将 node 节点一起启动加入集群。所以这里建议将 node 节点配置好后一起启动,如有报错查看日志:

journalctl -xe -u etcd
tail -100 /var/log/messages

3.5 查看集群状态

/opt/kubernetes/bin/etcdctl \
--ca-file=/opt/kubernetes/ssl/ca.pem \
--cert-file=/opt/kubernetes/ssl/server.pem \
--key-file=/opt/kubernetes/ssl/server-key.pem \
--endpoints="https://192.168.0.3:2379,https://192.168.0.4:2379,https://192.168.0.5:2379" \
cluster-health

member 215f6fa14c83114a is healthy: got healthy result from https://192.168.0.4:2379
member 3179d851e2d8e401 is healthy: got healthy result from https://192.168.0.5:2379
member e5597d27b776a481 is healthy: got healthy result from https://192.168.0.3:2379
cluster is healthy

四、部署 Flannel 网络

Flannel 是 Overlay 网络的一种,也是将源数据包封装在另一种网络包里面进行路由转发和通信,目前已经支持 UDP、VXLAN、AWS VPC 和 GCE 路由等数据转发方式。

4.1 分配子网段写入到 etcd,供 flanneld 使用

配置 flanneld 分配的子网段,写入到 etcd 集群(在任意 etcd 集群主机操作):

/opt/kubernetes/bin/etcdctl \
--ca-file=/opt/kubernetes/ssl/ca.pem \
--cert-file=/opt/kubernetes/ssl/server.pem \
--key-file=/opt/kubernetes/ssl/server-key.pem \
--endpoints=https://192.168.0.3:2379,https://192.168.0.4:2379,https://192.168.0.5:2379 \
set /kubernetes/network/config '{"Network":"172.17.0.0/16","SubnetLen":24,"Backend":{"Type":"vxlan"}}'

查看子网:

/opt/kubernetes/bin/etcdctl \
--ca-file=/opt/kubernetes/ssl/ca.pem \
--cert-file=/opt/kubernetes/ssl/server.pem \
--key-file=/opt/kubernetes/ssl/server-key.pem \
--endpoints=https://192.168.0.3:2379,https://192.168.0.4:2379,https://192.168.0.5:2379 \
get /kubernetes/network/config

4.2 下载 flanneld

一般在 node 节点部署,这里在 master 下载然后复制到 node:

wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
tar zxvf flannel-v0.11.0-linux-amd64.tar.gz

传输到 node1 和 node2 节点:

scp flanneld mk-docker-opts.sh root@192.168.0.4:/opt/kubernetes/bin/
scp flanneld mk-docker-opts.sh root@192.168.0.5:/opt/kubernetes/bin/

4.3 编辑 flanneld 配置文件 [node1][node2]

cat << EOF | tee /opt/kubernetes/cfg/flanneld
FLANNEL_OPTIONS="--etcd-endpoints=https://192.168.0.3:2379,https://192.168.0.4:2379,https://192.168.0.5:2379 \
-etcd-cafile=/opt/kubernetes/ssl/ca.pem \
-etcd-certfile=/opt/kubernetes/ssl/server.pem \
-etcd-keyfile=/opt/kubernetes/ssl/server-key.pem \
-etcd-prefix=/kubernetes/network"
EOF

4.4 创建 systemd unit 文件来管理 flanneld [node1][node2]

cat << EOF | tee /usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target network-online.target etcd.service
Wants=network-online.target
Before=docker.service

[Service]
Type=notify
EnvironmentFile=/opt/kubernetes/cfg/flanneld
ExecStart=/opt/kubernetes/bin/flanneld -ip-masq $FLANNEL_OPTIONS
ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

4.5 在 node 节点启动 flanneld [node1][node2]

systemctl start flanneld
systemctl enable flanneld

4.6 配置 docker 指定子网启动 [node1][node2]

在 node 节点重新编辑 docker unit 文件:

vim /usr/lib/systemd/system/docker.service

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
BindsTo=containerd.service
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target

4.7 加载配置文件,并重启 [node1][node2]

systemctl daemon-reload
systemctl enable flanneld && systemctl restart flanneld
systemctl restart docker

五、部署 kubectl 工具,创建 kubeconfig 文件

kubectl 是 kubernetes 的集群管理工具,任何节点通过 kubetcl 都可以管理整个 k8s 集群。这里是在 master 节点安装 kubectl 工具,创建 Node 节点 kubeconfig 文件。

kubectl 是通过下面创建的 kubelet kubeconfig 文件获取来 kube-apiserver 地址、证书、用户名等信息。

5.1 下载安装 kubectl [master]

wget https://dl.k8s.io/v1.13.6/kubernetes-client-linux-amd64.tar.gz
tar zxvf kubernetes-client-linux-amd64.tar.gz
cp kubernetes/client/bin/kubectl /opt/kubernetes/bin/

5.2 创建 TLS Bootstrapping Token [master]

cd /opt/kubernetes/cfg
head -c 16 /dev/urandom | od -An -t x | tr -d ' ' > token
echo "$(cat token),kubelet-bootstrap,10001,\"system:kubelet-bootstrap\"" > token.csv

配置 kubelet kubeconfig,用于 kubelet 自动签发证书,kubelet 访问 kube-apiserver 的时候是通过 bootstrap.kubeconfig 进行用户验证。

# 设置集群参数,--server 需要指定 master 节点 ip
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.0.3:6443 \
--kubeconfig=bootstrap.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
--token=$(cat token) \
--kubeconfig=bootstrap.kubeconfig

# 设置上下文参数
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig

# 设置默认上下文
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

5.3 创建 kube-proxy kubeconfig [master]

# 设置集群参数,--server参数为 master ip
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.0.3:6443 \
--kubeconfig=kube-proxy.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials kube-proxy \
--client-certificate=/opt/kubernetes/ssl/kube-proxy.pem \
--client-key=/opt/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

5.4 复制创建好的配置文件到 node 节点

scp *.kubeconfig root@192.168.0.4:/opt/kubernetes/cfg/ 
scp *.kubeconfig root@192.168.0.5:/opt/kubernetes/cfg/

六、部署 master 节点

6.1 下载解压 [master]

wget https://dl.k8s.io/v1.13.6/kubernetes-server-linux-amd64.tar.gz
tar zxvf kubernetes-server-linux-amd64.tar.gz
cp -r kubernetes/server/bin/{kube-apiserver,kube-controller-manager,kube-scheduler,kubectl,kube-proxy,kubelet} /opt/kubernetes/bin/

kube-scheduler、kube-controller-manager 一般和 kube-apiserver 部署在同一台机器上,它们使用非安全端口和 kube-apiserver通信; 

6.2 配置和启动 kube-apiserver [master]

kube-apiserver 是集群的统一入口,各组件协调者,以 HTTP API 提供接口服务,所有对象资源的增删改查和监听操作都交给 APIServer 处理后再提交给 etcd 存储。

cat << EOF | tee /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://192.168.0.3:2379,https://192.168.0.4:2379,https://192.168.0.5:2379 \
--insecure-bind-address=127.0.0.1 \
--bind-address=192.168.0.3 \
--insecure-port=8080 \
--secure-port=6443 \
--advertise-address=192.168.0.3 \
--allow-privileged=true \
--service-cluster-ip-range=10.10.10.0/24 \
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--kubelet-https=true \
--enable-swagger-ui=true \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/opt/kubernetes/ssl/server.pem \
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/server.pem \
--etcd-keyfile=/opt/kubernetes/ssl/server-key.pem"
EOF

参数解释:

--logtostderr=true                  # 启用错误日志
--v=4                               # 错误日志级别
--etcd-servers=                     # etcd集群地址
--insecure-bind-address=127.0.0.1   # 非安全的端口绑定地址,不对外
--bind-address=192.168.0.3          # 安全的端口绑定地址,https加密,对外
--insecure-port=8080                # 非安全端口
--secure-port=6443                  # 安全端口
--advertise-address=192.168.0.3     # 通告地址,用于集群通信
--allow-privileged=true             # 启用授权,启用后容器访问内核权限和宿主机一样
--service-cluster-ip-range=10.10.10.0/24     # 指定 Service Cluster IP 地址段,该地址段不能路由可达
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction   # 准入模块,做一些授权认证
--authorization-mode=RBAC,Node      # 指定在安全端口使用 RBAC 授权模式,拒绝未通过授权的请求,RBAC(基于角色访问控制)
--kubelet-https=true                # 启用https访问
--enable-bootstrap-token-auth       # 启用 bootstrap 引导证书生成
--token-auth-file=/opt/kubernetes/cfg/token.csv               # token 认证文件路径
--service-node-port-range=30000-50000                         # service 节点端口范围
--tls-cert-file=/opt/kubernetes/ssl/server.pem                # 证书路径
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem     # 证书路径
--client-ca-file=/opt/kubernetes/ssl/ca.pem                   # 证书路径
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem     # 证书路径
--etcd-cafile=/opt/kubernetes/ssl/ca.pem                      # 证书路径
--etcd-certfile=/opt/kubernetes/ssl/server.pem                # 证书路径
--etcd-keyfile=/opt/kubernetes/ssl/server-key.pem             # 证书路径

创建 systemd unit 文件来管理 kube-apiserver:

cat << EOF | tee /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
After=network.target etcd.service
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver
ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

启动:

systemctl daemon-reload
systemctl start kube-apiserver && systemctl enable kube-apiserver

6.4 配置和启动 kube-controller-manager [master]

kube-controller-manager 用来处理集群中常规后台任务,一个资源对应一个控制器,而 ControllerManager 就是负责管理这些控制器的。

cat << EOF | tee /opt/kubernetes/cfg/kube-controller-manager
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \
--v=4 \
--master=127.0.0.1:8080 \
--leader-elect=true \
--address=127.0.0.1 \
--service-cluster-ip-range=10.10.10.0/24 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
--root-ca-file=/opt/kubernetes/ssl/ca.pem"
EOF

参数解释:

--logtostderr=true                  # 启用错误日志
--v=4                               # 错误日志级别
--master=127.0.0.1:8080             # 使用非安全8080端口与kube-apiserver通信
--leader-elect=true                 # 部署master集群时,选举一台处于工作状态的kube-controller-manager进程
--address=127.0.0.1                 # 值必须为127.0.0.1,因为当前kube-apiserver、scheduler、controller-manager在同一台机器
--service-cluster-ip-range=10.10.10.0/24   # 参数指定Cluster中Service的CIDR范围,该网络在各Node间必须路由不可达,必须和kube-apiserver中的参数一致
--cluster-name=kubernetes           # 集群名字
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem        # 指定的证书和私钥文件用来签名为 TLS BootStrap 创建的证书和私钥
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem     # 同上
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem  
--root-ca-file=/opt/kubernetes/ssl/ca.pem # 用来对kube-apiserver证书进行校验,指定该参数后,才会在Pod容器的ServiceAccount中放置该CA证书文件

创建 systemd unit 文件来管理 kube-controller-manager:

cat << EOF | tee /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager
ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
LimitNOFILE=65536
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

启动:

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

6.5 配置和启动 kube-scheduler [master]

kube-scheduler 根据调度算法为新创建的 Pod 选择一个 Node 节点。

cat << EOF | tee /opt/kubernetes/cfg/kube-scheduler
KUBE_SCHEDULER_OPTS="--logtostderr=true \
--v=4 \
--master=http://127.0.0.1:8080 \
--leader-elect"
EOF

创建 systemd unit 文件:

cat << EOF | tee /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
LimitNOFILE=65536
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

启动:

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

6.6 查看集群状态 [master]

kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok                  
scheduler            Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   

七、部署 node 节点

7.1 下载解压

wget https://dl.k8s.io/v1.13.6/kubernetes-node-linux-amd64.tar.gz
tar zxvf kubernetes-node-linux-amd64.tar.gz
scp kubernetes/node/bin/{kubelet,kube-proxy} root@192.168.0.4:/opt/kubernetes/bin/
scp kubernetes/node/bin/{kubelet,kube-proxy} root@192.168.0.5:/opt/kubernetes/bin/

7.2 配置启动 kubelet

kubelet 是 Master 在 Node 节点上的 Agent,管理本机运行容器的生命周期,比如创建容器、Pod 挂载数据卷、下载 secret、获取容器和节点状态等工作。kubelet 将每个 Pod 转换成一组容器。

kubelet 启动时向 kube-apiserver 发送 TLS bootstrapping 请求,需要先将 bootstrap token 文件中的kubelet-bootstrap用户赋予system:node-bootstrapper角色,然后 kubelet 才有权限创建认证请求。所以需要在 master 执行以下命令:

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

如果没有执行这个命令会报以下错误信息:

failed to run Kubelet: cannot create certificate signing request: certificatesigningrequests.certificates.k8s.io is forbidden: User "kubelet-bootstrap" cannot create resource "certificatesigningrequests" in API group "certificates.k8s.io" at the cluster scope

创建配置文件:

cat << EOF | tee /opt/kubernetes/cfg/kubelet
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--address=192.168.0.4 \
--hostname-override=192.168.0.4 \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--experimental-bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--cert-dir=/opt/kubernetes/ssl \
--allow-privileged=true \
--cluster-dns=10.10.10.2 \
--cluster-domain=cluster.local \
--fail-swap-on=false \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF

配置 systemd unit 文件:

cat << EOF | tee /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kubelet
ExecStart=/opt/kubernetes/bin/kubelet $KUBELET_OPTS
Restart=on-failure
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

启动:

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

7.3 在 master 执行 TLS 证书授权请求 [master]

kubelet 首次启动时向 kube-apiserver 发送证书签名请求,必须授权通过后,Node 才会加入到集群中 在三个节点都部署完 kubelet 之后,在 master节点执行授权操作:

[root@k8s-master ~]# kubectl get csr
NAME                                                   AGE   REQUESTOR           CONDITION
node-csr-2hXk3mD-fOggxuYJ8KqmlqC527Qxit0cW_GDWcQ_rtE   22m   kubelet-bootstrap   Pending
node-csr-Ry24c4r20ZR6nUaYsoLOLDTQ3JQMzX46RPFsedELrSE   27s   kubelet-bootstrap   Pending

[root@k8s-master ~]# kubectl get nodes
No resources found.

[root@k8s-master ~]# kubectl certificate approve node-csr-2hXk3mD-fOggxuYJ8KqmlqC527Qxit0cW_GDWcQ_rtE
certificatesigningrequest.certificates.k8s.io/node-csr-2hXk3mD-fOggxuYJ8KqmlqC527Qxit0cW_GDWcQ_rtE approved

[root@k8s-master ~]# kubectl certificate approve node-csr-Ry24c4r20ZR6nUaYsoLOLDTQ3JQMzX46RPFsedELrSE
certificatesigningrequest.certificates.k8s.io/node-csr-Ry24c4r20ZR6nUaYsoLOLDTQ3JQMzX46RPFsedELrSE approved

[root@k8s-master ~]# kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
192.168.0.4   Ready    <none>   59s   v1.13.6
192.168.0.5   Ready    <none>   48s   v1.13.6

7.4 配置启动 kube-proxy [node1][node2]

kube-proxy 在 Node 节点上实现 Pod 网络代理,维护网络规则和四层负载均衡工作。

创建配置文件:

cat << EOF | tee /opt/kubernetes/cfg/kube-proxy
KUBE_PROXY_OPTS="--logtostderr=true \
--v=4 \
--bind-address=192.168.0.4 \
--hostname-override=192.168.0.4 \
--cluster-cidr=10.10.10.0/24 \
--kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"
EOF

创建 systemd unit 文件:

cat << EOF | tee /usr/lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=-/opt/kubernetes/cfg/kube-proxy
ExecStart=/opt/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

启动:

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

7.5 查询集群状态

kubectl get node
kubectl get componentstatus
kubectl get pod -o wide

未完待续...

评论

想说点什么?