Skip to main content
开放网络的先行者与推动者—星融元
加入我们技术支持(Support)  TEL:(+86)4000989811
Kukernetes

Kubernetes部署方案

1 目标

K8S集群部署有几种方式:kubeadm、minikube和二进制包。前两者属于自动部署,简化部署操作。但自动部署屏蔽了很多细节,使得对各个模块感知很少,本文主要采用二进制包手动部署。

部署过程中所涉及到的设备、接口及管理网口的IP地址如下表所示:

设备名称IP地址组件
master192.168.4.154etcd
kube-apiserver
kube-controller-manager
kube-scheduler
node1192.168.4.155etcd
kubelet
kube-proxy
docker
node2192.168.4.156etcd
kubelet
kube-proxy
docker

表1:设备管理口IP及组件列表

2 硬件与软件环境

部署环境中涉及到的硬件和软件如表2和表3所示:

名称型号硬件指标数量备注
服务器CPU:至少2核
内存:最低2
磁盘:不少于20G
3

表2:硬件环境

软件版本备注
操作系统Centos7.6安装时选择Compute Node 模式
Kubernetes1.18.0
DockerDocker-ce19.03
Etcd3.3.11

表3:软件环境

3 Kubernetes简介

Kubernetes 是是一个基于容器技术的分布式架构领先方案。Kubernetes(k8s)是Google开源的容器集群管理系统,Kubernetes简称K8S,K8S用于容器化应用程序的部署,扩展和管理。K8S提供了容器编排,资源调度,弹性伸缩,部署管理,服务发现等一系列功能。

  • Kubernetes集群架构
图1: Kubernetes集群架构图
  • Kubernetes核心概念

cluster

cluster是 计算、存储和网络资源的集合,k8s利用这些资源运行各种基于容器的应用。

master

master是cluster的大脑,他的主要职责是调度,即决定将应用放在那里运行。master运行linux操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个master。

node

node的职责是运行容器应用。node由master管理,node负责监控并汇报容器的状态,同时根据master的要求管理容器的生命周期。node运行在linux的操作系统上,可以是物理机或者是虚拟机。

pod

pod是k8s的最小工作单元。每个pod包含一个或者多个容器。pod中的容器会作为一个整体被master调度到一个node上运行。

controller-manager

k8s通常不会直接创建pod,而是通过controller-manager来管理pod的。controller-manager中定义了pod的部署特性,比如有几个副本,在什么样的node上运行等。为了满足不同的业务场景,k8s提供了多种controller-manager,包括deployment、replicaset、daemonset、statefulset、job等。

1) deployment
是最常用的controller。deployment可以管理pod的多个副本,并确保pod按照期望的状态运行。

2) replicaset
实现了pod的多副本管理。使用deployment时会自动创建replicaset,也就是说deployment是通过replicaset来管理pod的多个副本的,我们通常不需要直接使用replicaset。

3) daemonset
用于每个node最多只运行一个pod副本的场景。正如其名称所示的,daemonset通常用于运行daemon。

4) statefuleset
能够保证pod的每个副本在整个生命周期中名称是不变的,而其他controller不提供这个功能。当某个pod发生故障需要删除并重新启动时,pod的名称会发生变化,同时statefulset会保证副本按照固定的顺序启动、更新或者删除。、

5) job
用于运行结束就删除的应用,而其他controller中的pod通常是长期持续运行的。

service

deployment可以部署多个副本,每个pod 都有自己的IP,外界通过service访问这些副本。

k8s的 service定义了外界访问一组特定pod的方式。service有自己的IP和端口,service为pod提供了负载均衡。
k8s运行容器pod与访问容器这两项任务分别由controller和service执行。

namespace

可以将一个物理的cluster逻辑上划分成多个虚拟cluster,每个cluster就是一个namespace。不同的namespace里的资源是完全隔离的。

lable

标签用于区分对象(比如pod、service),键/值对存在;每个对象可以有多个标签,通过标签关联对象。

  • K8s的Master组件

kube-apiserver

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

kube-controller-manager

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

kube-scheduler

根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。

Etcd

分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息。

  • K8s的Node组件

Kubelet

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

kube-proxy

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

docker或rocket

容器引擎,运行容器。

4 安装步骤

4.1 准备环境

注意:以下步骤各节点统一执行

  • 关闭交换分区:
[root@localhost ~]#swapoff -a && sysctl -w vm.swappiness=0
  • 注释掉开机启动交换分区:
[root@localhost ~]sed -i 's/.*swap.*/#&/g' /etc/fstab
  • 关闭防火墙:
[root@localhost ~]systemctl stop firewalld 
[root@localhost ~] systemctl disable firewalld
  • 禁用Selinux:
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
  • 设置透明网桥:
[root@localhost ~]#cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
  • 安装Docker:
[root@localhost ~]# yum -y install yum-utils 
[root@localhost ~]# yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
[root@localhost ~]#yum install docker-ce
[root@localhost ~]#curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://bc437cce.m.daocloud.io
[root@localhost ~]# systemctl enable docker
[root@localhost ~]#systemctl start docker
  • 同步时间:
[root@localshot  ~]# yum -y install ntp
[root@localhost  ~]# vi /etc/ntp.conf
修改server ntp1.aliyun.com iburst 
[root@localhost  ~]# systemctl restart ntpd
[root@localhost  ~]# timedatectl set-timezone Asia/Shanghai
[root@localhost  ~]#cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  • 修改系统打开文件最大数量:
[root@localhost  ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

4.2 部署Etcd集群

  • 下载cfssl工具并生成证书:

下载cfssl工具

[root@k8s-master ~]#wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@k8s-master ~]#wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@k8s-master ~]#wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@k8s-master ~]#chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
[root@k8s-master ~]#mv cfssl_linux-amd64 /usr/local/bin/cfssl
[root@k8s-master ~]#mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
[root@k8s-master ~]#mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

创建以下三个文件:

[root@k8s-master ~]#vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
[root@k8s-master ~]#vim ca-csr.json
{
    "CN": "etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
} 
[root@k8s-master ~]#vim server-csr.json
{
    "CN": "etcd",
    "hosts": [
    "192.168.4.154",
"192.168.4.155",
"192.168.4.156"
],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
} 

生成证书

[root@k8s-master ~]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
[root@k8s-master ~]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
[root@k8s-master ~]# ls *pem
ca-key.pem  ca.pem  server-key.pem  server.pem
  • 安装Etcd3:

创建文件夹

[root@k8s-master ~]# mkdir /opt/etcd/{bin,cfg,ssl} -p

下载etcd相关包

[root@k8s-master ~]#wget https://github.com/etcd-io/etcd/releases/download/v3.2.12/etcd-v3.2.12-linux-amd64.tar.gz 
[root@k8s-master ~]#tar zxvf etcd-v3.2.12-linux-amd64.tar.gz 
[root@k8s-master ~]#mv etcd-v3.2.12-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

创建etcd配置⽂件

[root@k8s-master ~]#vim /opt/etcd/cfg/etcd
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.4.154:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.4.154:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.4.154:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.4.154:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.4.154:2380,etcd02=https://192.168.4.155:2380,etcd03=https://192.168.4.156:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
  • ETCD_NAME 节点名称
  • ETCD_DATA_DIR 数据⽬录
  • ETCD_LISTEN_PEER_URLS 集群通信监听地址
  • ETCD_LISTEN_CLIENT_URLS 客户端访问监听地址
  • ETCD_INITIAL_ADVERTISE_PEER_URLS 集群通告地址
  • ETCD_ADVERTISE_CLIENT_URLS 客户端通告地址
  • ETCD_INITIAL_CLUSTER 集群节点地址
  • ETCD_INITIAL_CLUSTER_TOKEN 集群Token
  • ETCD_INITIAL_CLUSTER_STATE 加⼊集群的当前状态,new是新集群,existing表⽰加⼊已有集群

修改etcd开机启动

[root@k8s-master ~]# vim  /usr/lib/systemd/system/etcd.service 
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd
ExecStart=/opt/etcd/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_TOKEN} \
--initial-cluster-state=new \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

把刚才生成的证书拷贝到配置文件中的位置:

[root@k8s-master ~]# cp ca*pem server*pem /opt/etcd/ssl

启动etcd并设置开机启动:

[root@k8s-master ~]# systemctl enable etcd
[root@k8s-master ~]# systemctl start etcd

注:三台机器的etcd要同时启动,否则会失败。

检查etcd集群状态:

[root@k8s-master ~]# /opt/etcd/bin/etcdctl \
--ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/server.pem  \
--key-file=/opt/etcd/ssl/server-key.pem  \
--endpoints="https://192.168.4.154:2379,https://192.168.4.155:2379,https://192.168.4.156:2379"  \
cluster-health

4.3 安装运行Master节点组件

  • 下载组件:
[root@ k8s-master ~]#wget https://dl.k8s.io/v1.18.8/kubernetes-server-linux-amd64.tar.gz
  • 解压组件包:
[root@k8s-master ~]# tar zxvf kubernetes-server-linux-amd64.tar.gz
[root@k8s-master ~]#mkdir /opt/kubernetes/{bin,cfg,ssl,logs}  -p
[root@k8s-master ~]#cp kubernetes/server/bin/{kube-apiserver,kube-scheduler,kube-controller-manager,kubectl,kubelet}  /opt/kubernetes/bin
  • 生成证书

创建CA证书:

[root@k8s-master ~]# vim  ca-config.json                 
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}

[root@k8s-master ~]#vim ca-csr.json 
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
[root@k8s-master ~]#cfssl gencert -initca ca-csr.json | cfssljson -bare ca –

生成apiserver证书:

[root@k8s-master ~]#vim server-csr.json
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",//这是后面dns要使用的虚拟网络的网关,不用改,就用这个 切忌(删除这行)
      "127.0.0.1",
      "192.168.4.154",
      "192.168.4.155",
      "192.168.4.156",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
[root@k8s-master ~]#cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

生成kube-proxy证书:

[root@k8s-master ~]#vim  kube-proxy-csr.json 
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
[root@k8s-master ~]#cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

最终生成以下证书文件:

[root@k8s-master ~]## ls *pem
ca-key.pem  ca.pem  kube-proxy-key.pem  kube-proxy.pem  server-key.pem  server.pem

如果有多个master,需要将证书拷贝到所有的 master节点

[root@k8s-master ~]#scp server.pem  server-key.pem ca.pem ca-key.pem k8s-master2:/opt/kubernetes/ssl/

创建token文件

#生成随机token
[root@k8s-master ~]#head -c 16 /dev/urandom | od -An -t x | tr -d ' '
[root@k8s-master ~]#cat << EOF >/opt/kubernetes/cfg/token.csv 
79d370bf4b3e1bda79087504d34b9e5d,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
第一列:随机字符串,自己可生成,第二列:用户名,第三列:UID,第四列:用户组
  • 配置apiserver

创建配置文件:

[root@k8s-master~]# vim  /opt/kubernetes/cfg/kube-apiserver 
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=https://192.168.4.154:2379,https://192.168.4.155:2379,https://192.168.4.156:2379 \
--bind-address=192.168.4.154 \
--secure-port=6443 \
--advertise-address=192.168.4.154 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--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/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem"


配置好前面生成的证书,确保能连接etcd。
参数说明:
* --logtostderr 启用日志
* --v 日志等级
* --etcd-servers etcd集群地址
* --bind-address 监听地址
* --secure-port https安全端口
* --advertise-address 集群通告地址
* --allow-privileged 启用授权
* --service-cluster-ip-range Service虚拟IP地址段
* --enable-admission-plugins 准入控制模块
* --authorization-mode 认证授权,启用RBAC授权和节点自管理
* --enable-bootstrap-token-auth 启用TLS bootstrap功能,后面会讲到
* --token-auth-file token文件
* --service-node-port-range Service Node类型默认分配端口范围

创建systemd服务文件:

[root@k8s-master~]#vim  /usr/lib/systemd/system/kube-apiserver.service 
[Unit]
Description=Kubernetes API Server
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

[Install]
WantedBy=multi-user.target

启动服务,并设置开机启动:

[root@k8s-master~]#systemctl daemon-reload
[root@k8s-master~]#systemctl enable kube-apiserver
[root@k8s-master~]#systemctl restart kube-apiserver

注意:apiserver默认支持etcd3,如果是etcd2,需启动时指定版本选项–storage-backend=etcd2

  • 配置scheduler

创建配置文件:

[root@k8s-master~]#cat <<  EOF >/opt/kubernetes/cfg/kube-scheduler 
KUBE_SCHEDULER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/opt/kubernetes/logs \
--master=127.0.0.1:8080 \
--leader-elect"
EOF

参数说明:
* --master 连接本地apiserver
* --leader-elect 当该组件启动多个时,自动选举(HA)

创建systemd服务文件:

[root@k8s-master~]#vim /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

[Install]
WantedBy=multi-user.target

启动服务,并设置开机启动:

[root@k8s-master~]#systemctl daemon-reload
[root@k8s-master~]#systemctl enable kube-scheduler
[root@k8s-master~]#systemctl restart kube-scheduler
  • 配置controller-manager

创建配置文件:

[root@k8s-master~]# vim  /opt/kubernetes/cfg/kube-controller-manager 
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/opt/kubernetes/logs \
--master=127.0.0.1:8080 \
--leader-elect=true \
--address=127.0.0.1 \
--service-cluster-ip-range=10.0.0.0/24 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \
--root-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem"

创建systemd服务文件:

[root@k8s-master~]#vim /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

[Install]
WantedBy=multi-user.target

启动服务,并设置开机启动:

[root@k8s-master~]#systemctl daemon-reload
[root@k8s-master~]#systemctl enable kube-controller-manager
[root@k8s-master~]#systemctl restart kube-controller-manager

注意:几个组件启动顺序有依赖,需要先启动etcd,再启动apiserver,其他组件无顺序要求

所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:

[root@k8s-master~]# ln -s  /opt/kubernetes/bin/kubectl  /usr/bin/
[root@k8s-master~]# kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   
controller-manager   Healthy   ok
如上输出说明组件都正常。
  • 查看启动日志的方法
[root@k8s-master~]# journalctl -u kube-apiserver

将kubelet-bootstrap用户绑定到系统集群角色

[root@k8s-master~]#/opt/kubernetes/bin/kubectl create clusterrolebinding kubelet-bootstrap \
  --clusterrole=system:node-bootstrapper \
  --user=kubelet-bootstrap

创建kubeconfig文件:

在生成kubernetes证书的目录下执行以下命令生成kubeconfig文件:

指定apiserver 地址(如果apiserver做了负载均衡,则填写负载均衡地址)
KUBE_APISERVER="https://192.168.4.154:6443"
BOOTSTRAP_TOKEN=79d370bf4b3e1bda79087504d34b9e5d

设置集群参数

[root@k8s-master~] #/opt/kubernetes/bin/kubectl config set-cluster kubernetes \
--certificate-authority=./ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig

设置客户端认证参数

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config set-credentials kubelet-bootstrap \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=bootstrap.kubeconfig

设置上下文参数

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config set-context default \
  --cluster=kubernetes \
  --user=kubelet-bootstrap \
  --kubeconfig=bootstrap.kubeconfig

设置默认上下文

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

创建kube-proxy kubeconfig文件

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config set-cluster kubernetes \
  --certificate-authority=./ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config set-credentials kube-proxy \
  --client-certificate=./kube-proxy.pem \
  --client-key=./kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig

[root@k8s-master~]#/opt/kubernetes/bin/kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

[root@k8s-master~]# ls
bootstrap.kubeconfig  kube-proxy.kubeconfig

注:将这两个文件拷贝到Node节点/opt/kubernetes/cfg目录下。

4.4 安装运行Node节点组件

  • 下载组件
[root@k8s-node01 ~]#wget https://dl.k8s.io/v1.18.8/kubernetes-client-linux-amd64.tar.gz
  • 解压组件包:
[root@k8s-node01 ~]#tar zxvf kubernetes-client-linux-amd64.tar.gz
[root@k8s-node01 ~]#cp  kubernetes/client/bin/kubectl   /opt/kubernetes/bin/
[root@k8s-node01 ~]#mkdir -p /opt/kubernetes/{bin,cfg,ssl}
[root@k8s-node01 ~]#scp root@192.168.4.154:/root/kubernetes/server/bin/{kubelet,kube-proxy} /opt/kubernetes/bin/
  • 配置kubelet

创建kubelet配置文件:

[root@k8s-node01 ~]# cat << EOF >/opt/kubernetes/cfg/kubelet 
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/opt/kubernetes/logs \
--hostname-override=192.168.4.155 \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--config=/opt/kubernetes/cfg/kubelet.config \
--cert-dir=/opt/kubernetes/ssl  \
--network-plugin=cni \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF

参数说明:
* --hostname-override 在集群中显示的主机名
* --kubeconfig 指定kubeconfig文件位置,会自动生成
* --bootstrap-kubeconfig 指定刚才生成的bootstrap.kubeconfig文件
* --cert-dir 颁发证书存放位置
* --pod-infra-container-image 管理Pod网络的镜像

创建kube.config配置文件:

[root@ k8s-node01 ~]# cat << EOF > /opt/kubernetes/cfg/kubelet.config  
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 192.168.4.155
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS: ["10.0.0.2"]
clusterDomain: cluster.local.
failSwapOn: false
authentication:
  anonymous:
    enabled: true 
  webhook:
    enabled: false
EOF

创建systemd服务文件:

[root@k8s-node01 ~]#vim /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

启动服务,并设置开机启动:

[root@k8s-node01 ~]#systemctl daemon-reload
[root@k8s-node01 ~]#systemctl enable kubelet 
[root@k8s-node01 ~]#systemctl restart kubelet

在Master审批Node加入集群:

启动后还没加入到集群中,需要手动允许该节点才可以。在Master节点查看请求签名的Node:

[root@k8s-master~]# /opt/kubernetes/bin/kubectl get csr
[root@k8s-master~]#/opt/kubernetes/bin/kubectl certificate approve XXXXID
[root@k8s-master~]#/opt/kubernetes/bin/kubectl get node
  • 配置kube-proxy

创建kube-proxy配置文件:

[root@k8s-node01 ~]#vim /opt/kubernetes/cfg/kube-proxy 
KUBE_PROXY_OPTS="--logtostderr=true \
--v=4 \
--log-dir=/opt/kubernetes/logs \
--hostname-override=192.168.4.155 \
--cluster-cidr=10.0.0.0/24 \           //不要改,就是这个ip
--kubeconfig=/opt/kubernetes/cfg/kube-proxy.kubeconfig"

创建systemd服务文件:

[root@k8s-node01 ~]# vim /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

启动服务,并设置开机启动:

[root@k8s-node01 ~]#systemctl daemon-reload
[root@k8s-node01 ~]#systemctl enable kube-proxy
[root@k8s-node01 ~]#systemctl restart kube-proxy

注意:其他节点加入集群与k8s-node01方式相同,但需修改kubelet的–address和–hostname-override选项为本机IP。

查看集群状态

[root@k8s-master~]# /opt/kubernetes/bin/kubectl get node
[root@k8s-master~]# /opt/kubernetes/bin/kubectl get cs

查看启动日志的方法

[root@k8s-master~]# journalctl -u kubelet

4.5 部署Flannel网络

图2: Flannel原理架构图
  • 下载组件并定义网段

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

[root@k8s-master ~]#wget https://github.com/coreos/flannel/releases/download/v0.12.0/flannel-v0.12.0-linux-amd64.tar.gz
[root@k8s-master ~]#/opt/etcd/bin/etcdctl \
--ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \
--endpoints="https://192.168.4.154:2379,https://192.168.4.155:2379,https://192.168.4.156:2379" \
set /coreos.com/network/config  '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'

以下部署步骤在每个node节点都操作

  • 下载二进制包:
#wget https://github.com/coreos/flannel/releases/download/v0.12.0/flannel-v0.12.0-linux-amd64.tar.gz
mkdir -pv /opt/kubernetes/bin
tar -zxvf flannel-v0.12.0-linux-amd64.tar.gz
mv flanneld mk-docker-opts.sh /opt/kubernetes/bin
  • 配置Flannel:
# mkdir -p /opt/kubernetes/cfg/
# vim /opt/kubernetes/cfg/flanneld
FLANNEL_OPTIONS="--etcd-endpoints=https://192.168.4.154:2379,https://192.168.4.155:2379, https://192.168.4.156:2379 \
 --etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem  \
--log-dir=/opt/kubernetes/logs "
  • systemd管理Flannel:
# vi /usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network-online.target network.target
Before=docker.service

[Service]
Type=notify
EnvironmentFile=/opt/kubernetes/cfg/flanneld
ExecStart=/opt/kubernetes/bin/flannel  $FLANNEL_OPTIONS --ip-masq=true --etcd-prefix=/coreos.com/network
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
  • 配置Docker启动指定子网段:
#vi /usr/lib/systemd/system/docker.service 
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

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

[Install]
WantedBy=multi-user.target
  • 从其他节点拷贝证书文件到node1和node2上:flanel需要证书
scp /opt/etcd/ssl/*  k8s-node1:/opt/etcd/ssl/
  • 重启flannel和docker:
systemctl daemon-reload
systemctl restart flanneld
systemctl enable flanneld
systemctl restart docker
  • 检查是否生效:
#ps -ef |grep docker
root     20941     1  1 Jun28 ?        09:15:34 /usr/bin/dockerd --bip=172.17.34.1/24 --ip-masq=false --mtu=1450
#ip addr
3607: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN 
    link/ether 8a:2e:3d:09:dd:82 brd ff:ff:ff:ff:ff:ff
    inet 172.17.34.0/32 scope global flannel.1
       valid_lft forever preferred_lft forever
3608: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP 
    link/ether 02:42:31:8f:d3:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.34.1/24 brd 172.17.34.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:31ff:fe8f:d302/64 scope link 
       valid_lft forever preferred_lft forever

确保docker0与flannel.1在同一网段。

测试不同节点互通,在当前节点访问另一个Node节点docker0 IP:

[root@k8s-master ~]## ping 172.17.58.1
PING 172.17.58.1 (172.17.58.1) 56(84) bytes of data.
64 bytes from 172.17.58.1: icmp_seq=1 ttl=64 time=0.263 ms
64 bytes from 172.17.58.1: icmp_seq=2 ttl=64 time=0.204 ms
如果能通说明Flannel部署成功。如果不通检查下日志:journalctl -u flannel

4.6 部署Calico网络

  • 关闭Flannel服务(在各node节点)
[root@k8s-node1 ~]# systemctl stop flanneld
[root@k8s-node1 ~]#systemctl disable flanneld
[root@k8s-node1 ~]# systemctl status flanneld
  • 重启所有节点
  • 下载官方yaml文件(在Master节点操作)
# wget https://docs.projectcalico.org/manifests/calico-etcd.yaml
# mv calico-etcd.yaml calico.yaml
  • 配置calico
calico# vim calico.yaml
data:
  # Configure this with the location of your etcd cluster.
  etcd_endpoints: " https://192.168.4.154:2379,https://192.168.4.155:2379,https://192.168.4.156:2379"
  
  # If you're using TLS enabled etcd uncomment the following.
  # You must also populate the Secret below with these files.  
  etcd_ca: "/calico-secrets/etcd-ca"   #取消原来的注释即可
  etcd_cert: "/calico-secrets/etcd-cert"
  etcd_key: "/calico-secrets/etcd-key"
  
  apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: calico-etcd-secrets
  namespace: kube-system
data:  
 etcd-key: (cat /etc/kubernetes/ssl/etcd-key.pem | base64 | tr -d '\n') #将输出结果填写在这里
  etcd-cert: (cat /etc/kubernetes/ssl/etcd.pem | base64 | tr -d '\n') #将输出结果填写在这里
  etcd-ca: (cat /etc/kubernetes/ssl/ca.pem | base64 | tr -d '\n') #将输出结果填写在这里
   #如果etcd没用启用tls则为null 
  #上面是必须要修改的参数,文件中有一个参数是设置pod network地址的,根据实际情况做修改:
   - name: CALICO_IPV4POOL_CIDR
value: "10.37.0.0/16"
  • 修改kubelet配置

设置各node上Kubelet服务的启动参数: –network-plugin=cni,

设置 master上的kube-apiserver服务的启动参数: –allow-privileged=true (因为calico-node需要以特权模式运行在各node上)

设置好后,重新启动kubelet。

这样通过calico就完成了Node间容器网络的设置 ,在后续的pod创建过程中,Kubelet将通过CNI接口调用 calico进行Pod的网络设置包括IP地址,路由规则,Iptables规则

  • 验证各Node间网络联通性:

kubelet启动后主机上就生成了一个tunl0接口。

#第一台Node查看:

[root@k8s-node1 ~]#ip route
172.16.169.128/26 via 192.168.4.156 dev tunl0 proto bird onlink

#第二台Node查看:

[root@k8s-node1 ~]#ip route
172.16.36.64/26 via 192.168.4.155 dev tunl0 proto bird onlink

#每台node上都自动设置了到其它node上pod网络的路由,去往其它节点的路都是通过tunl0接口,这就是IPIP模式。

如果设置CALICO_IPV4POOL_IPIP=”off” ,即不使用IPIP模式,则Calico将不会创建tunl0网络接口,路由规则直接使用物理机网卡作为路由器转发。

4.7 部署WebUI

  • 下载官方的yaml文件
[root@k8s-master~]#wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml 
  • 修改recommended.yaml

修改Service的NodePort便于我们从集群外使用浏览器访问dashboard
service段配置更改如下:(NodePort: 30001可以省略,缺省则为随机端口)

  • 执行安装
[root@k8s-master~]# kubectl create -f recommended.yaml 
  • 创建 serviceaccount
[root@k8s-master~]# vi  dashboard-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard
  • 执行安装
[root@k8s-master~]# kubectl create -f dashboard-sa.yaml
  • 创建clusterrolebinding为dashboard sa授权集群权限cluster-admin
[root@k8s-master~]# vi dashboard-clusterrolebinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: dashboard-admin
  namespace: kubernetes-dashboard
  • 执行安装
[root@k8s-master~]# kubectl create -f dashboard-clusterrolebinding
  • 获取token
[root@k8s-master~]# kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
  • 查看NodePort端口

如果按上面在NodePort配置成固定端口,就直接用固定端口访问即可

  • 访问页面

5 结果验证

运行一个测试示例,创建一个Nginx Web,判断集群是否正常工作:

  • 创建nginx.yaml
[root@k8s-master~]#vi nginx.yaml 
# API 版本号
apiVersion: apps/v1
# 类型,如:Pod/ReplicationController/Deployment/Service/Ingress
kind: Deployment
metadata:
  # Kind 的名称
  name: nginx-app
spec:
  selector:
    matchLabels:
      # 容器标签的名字,发布 Service 时,selector 需要和这里对应
      app: nginx
  # 部署的实例数量
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      # 配置容器,数组类型,说明可以配置多个容器
      containers:
      # 容器名称
      - name: nginx
        # 容器镜像
        image: nginx:1.17
        # 只有镜像不存在时,才会进行镜像拉取
        imagePullPolicy: IfNotPresent
        ports:
        # Pod 端口
        - containerPort: 80
  • 创建pods:
[root@k8s-master~]#kubectl  apply -f nginx.yaml
  • 查看pod详细信息:
[root@k8s-master~]# kubectl get pods
[root@k8s-master~]# kubectl get deployment
  • 暴露服务:
[root@k8s-master~]# kubectl expose deployment nginx-app --port=80 --type=LoadBalancer
  • 查看服务状态(查看对外的端口):
[root@k8s-master~]# kubectl get services
  • 浏览器校验
  • 删除pods

先删除pod

再删除对应的deployment

6 参考资料

如有其它问题,请填写右侧需求表单联系我们。www.asterfusion.com

A-lab-部署验证

对星融元产品感兴趣?

立即联系!

返回顶部

© 星融元数据技术(苏州)有限公司 苏ICP备17070048号-2