树莓派、openEuler、k8s、iSula,这些新奇的玩意碰撞在一起会产生什么样的化学反应呢?

01
集群规划
环境建议至少两台Master节点,两台Node节点;Etcd数据库可直接部署在Master或Node节点,机器比较充足的话,可以部署在单独的节点上。
本次我们要部署的集群是多Master高可靠性集群,包含3个Master,3个Node;在这6个节点中部署3个etcd数据库节点。集群拓扑图如下所示:

集群规划如下:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
02
环境准备
接下来将基于二进制包的方式,手动部署每个组件,来组成k8s高可用集群;首先是每台树莓派的操作系统镜像安装及配置初始化。
2.1
刷写树莓派镜像
我们需要给每个树莓派安装适合树莓派平台的openEuler镜像,镜像获取及相关操作可以参考openEuler社区里的raspberrypi sig组指引:

2.2
环境初始化
<1> 关闭防火墙
# systemctl stop firewalld
# systemctl disable firewalld
//临时生效
# setenforce 0
//临时关闭
# swapoff -a
# vi /etc/hosts
192.168.1.1 k8s-master1
192.168.1.2 k8s-master2
192.168.1.3 k8s-master3
192.168.1.4 k8s-node1
192.168.1.5 k8s-node2
192.168.1.6 k8s-node3
# vi /etc/hostname
k8s-master1
<5> 同步系统时间
各个节点之间需保持时间一致,因为自签证书是根据时间校验证书有效性,如果时间不一致,将校验不通过。
联网情况可使用如下命令(树莓派上ntpdate需要安装)
# ntpdate time.windows.com
# date -s 2020-11-18
# date -s 16:20:25
03
部署Etcd集群
3.1
自签证书
k8s集群安装配置过程中,会使用各种证书,目的是为了加强集群安全性。k8s提供了基于 CA签名的双向数字证书认证方式和简单的基于http base或token的认证方式,其中CA 证书方式的安全性最高。每个k8s集群都有一个集群根证书颁发机构(CA),集群中的组件通常使用CA来验证API server的证书,由API服务器验证kubelet客户端证书等。
证书生成操作可以在master节点上执行,证书只需要创建一次,以后在向集群中添加新节点时只要将证书拷贝到新节点上,并做一定的配置即可。我们计划在k8s-master2,k8s-master3及k8s-node1上部署etcd,下面就在 k8s-master2节点上来创建证书。
如下是k8s各个组件需要使用的证书:
|
|
|
|
|
|
|
|
|
|
<2> cfssl工具下载
我们通过cfssl工具来生成证书,通过以下链接下载arm平台的cfssl,目前只有arm32的工具,但是也可以用在arm64平台上。
# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-arm -o /usr/bin/cfssl
# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-arm -o /usr/bin/cfssljson
# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-arm -o /usr/bin/cfssl-certinfo
# chmod +x /usr/bin/cfssl*
3.2
自签Etcd SSL证书
首先为etcd签发一套SSL证书,通过如下命令创建几个目录,/k8s/etcd/ssl 用于存放etcd自签证书,/k8s/etcd/cfg用于存放etcd配置文件,/k8s/etcd/bin用于存放 etcd执行程序。
# mkdir -p /k8s/etcd/{ssl,cfg,bin}
# cd /k8s/etcd/ssl
# cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
signing:表示该证书可用于签名其它证书;生成的ca.pem证书中CA=TRUE;
profiles:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个profile;
expiry:证书过期时间;
server auth:表示client可以用该CA对server提供的证书进行验证;
client auth:表示server可以用该CA对client提供的证书进行验证。
执行如下命令创建ca-csr.json:
# cat > ca-csr.json <<EOF
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "etcd",
"OU": "System"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF
CN:Common Name,kube-apiserver从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
key:加密算法;
C:国家;
ST:地区;
L:城市;
O:组织,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group);
OU:组织单位。
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca

ca-key.pem:CA私钥;
ca.pem:CA数字证书。
<4> 创建证书签名请求文件:etcd-csr.json
执行如下命令创建 etcd-csr.json:
# cat > etcd-csr.json <<EOF
{
"CN": "etcd",
"hosts": [
"192.168.1.2",
"192.168.1.3",
"192.168.1.4"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "etcd",
"OU": "System"
}
]
}
EOF
hosts:需要指定授权使用该证书的IP或域名列表,这里配置所有etcd的IP地址;
key:加密算法及长度。
▲滑动查看更多
-ca:指定CA数字证书;
-ca-key:指定CA私钥;
-config:CA配置文件;
-profile:指定环境;
-hostname:指定证书所属的hostname或IP;
-bare:指定证书名前缀。

etcd-key.pem:etcd私钥;
etcd.pem:etcd数字证书。
证书生成完成,后面部署Etcd时主要会用到如下几个证书:

3.3
Etcd数据库集群部署
etcd集群采用一主多从架构模式部署,集群通过选举产生leader,因此需要部署奇数个节点(3/5/7)才能正常工作;etcd使用raft一致性算法保证每个节点的一致性。
从 github上下载合适版本的 etcd
# cd /k8s/etcd
# wget https://github.com/etcd-io/etcd/releases/download/v3.3.25/etcd-v3.3.25-linux-arm64.tar.gz
# tar -zxf etcd-v3.3.25-linux-arm64.tar.gz
# cp etcd-v3.3.25-linux-arm64/{etcd,etcdctl} /k8s/etcd/bin
▲滑动查看更多
说明:
ETCD_NAME:etcd在集群中的唯一名称
ETCD_DATA_DIR:etcd数据存放目录
ETCD_LISTEN_PEER_URLS:etcd集群间通讯的地址,设置为本机IP
ETCD_LISTEN_CLIENT_URLS:客户端访问的地址,设置为本机IP
ETCD_INITIAL_ADVERTISE_PEER_URLS:集群内部通讯地址,设置为本机IP
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址,设置为本机IP
ETCD_INITIAL_CLUSTER:集群节点地址,以 key=value 的形式添加各个 etcd 的地址
ETCD_INITIAL_CLUSTER_TOKEN:集群令牌,用于集群间做简单的认证
ETCD_INITIAL_CLUSTER_STATE:集群状态
ETCD_CERT_FILE:客户端 etcd 数字证书路径
ETCD_KEY_FILE:客户端 etcd 私钥路径
ETCD_TRUSTED_CA_FILE:客户端 CA 证书路径
ETCD_PEER_CERT_FILE:集群间通讯etcd数字证书路径
ETCD_PEER_KEY_FILE:集群间通讯etcd私钥路径
ETCD_PEER_TRUSTED_CA_FILE:集群间通讯CA证书路径
<3> 创建etcd服务:etcd.service
通过EnvironmentFile指定etcd.conf作为环境配置文件
# cat > /k8s/etcd/etcd.service <<EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/k8s/etcd/cfg/etcd.conf
ExecStart=/k8s/etcd/bin/etcd
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
etcd可以通过命令行选项和环境变量配置启动;命令行参数选项与环境变量命名的关系是命令行选项的小写字母转换成环境变量的大写字母时加一个“ETCD_”前缀,如:--name对应ETCD_NAME。
(注意:如果配置文件etcd.conf中已经定义了参数变量,则在etcd.service文件中ExecStart行不要再添加相同的启动参数,否则服务拉起的时候etcd会报参数冲突错误)
<4> 将etcd目录拷贝到另外两个节点
# scp -r /k8s root@k8s-master3:/k8s
# scp -r /k8s root@k8s-node1:/k8s
修改k8s-master3节点的/k8s/etcd/cfg/etcd.conf:
▲滑动查看更多
修改k8s-node1节点的 /k8s/etcd/cfg/etcd.conf:
▲滑动查看更多
首先在三个节点将etcd.service 拷贝到/usr/lib/systemd/system/下
# cp /k8s/etcd/etcd.service
/usr/lib/systemd/system/
# systemctl daemon-reload
在三个节点同时启动 etcd 服务
# systemctl start etcd
设置开机启动
# systemctl enable etcd
查看 etcd 集群状态
▲滑动查看更多

04
部署Master组件
4.1
自ApiServer SSL证书
k8s集群中所有资源的访问和变更都是通过kube-apiserver的REST API来实现的,首先在k8s-master2节点上部署kube-apiserver组件。
我们首先为apiserver签发一套SSL证书,过程与etcd自签SSL证书类似。通过如下命令创建几个目录,ssl用于存放自签证书,cfg用于存放配置文件,bin用于存放执行程序,logs存放日志文件。
# mkdir -p /k8s/kubernetes/{ssl,cfg,bin,logs}
进入kubernetes目录:
# cd /k8s/kubernetes/ssl
<1> 创建 CA 配置文件:ca-config.json
执行如下命令创建 ca-config.json
# cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
EOF
<2> 创建 CA 证书签名请求文件:ca-csr.json
# cat > ca-csr.json <<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "kubernetes",
"OU": "System"
}
],
"ca": {
"expiry": "87600h"
}
}
EOF
<3> 生成 CA 证书和私钥
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
<4> 创建证书签名请求文件:kubernetes-csr.json
执行如下命令创建 kubernetes-csr.json:
# cat > kubernetes-csr.json <<EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"10.0.0.1",
"192.168.1.1",
"192.168.1.2",
"192.168.1.3",
"192.168.1.4",
"192.168.1.5",
"192.168.1.6",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "kubernetes",
"OU": "System"
}
]
}
EOF
说明:
hosts:指定会直接访问apiserver的IP列表,一般需指定etcd集群、kubernetes master集群的主机IP和kubernetes服务的服务IP,Node的IP一般不需要加入。
<5> 为kubernetes生成证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
4.2
部署 kube-apiserver 组件
<1> 下载二进制包
▲滑动查看更多
解压后先将k8s-master2节点上部署的组件拷贝到/k8s/kubernetes/bin目录下:
▲滑动查看更多
<2> 创建Node令牌文件:token.csv
Master apiserver启用TLS认证后,Node节点kubelet组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情,因此有了 TLS Bootstrap 机制,kubelet会以一个低权限用户自动向 apiserver申请证书,kubelet的证书由apiserver动态签署。因此先为apiserver生成一个令牌文件,令牌之后会在Node中用到。
生成token,一个随机字符串,可使用如下命令生成token,apiserver配置的token必须与Node节点bootstrap.kubeconfig配置保持一致。
# head -c 16 /dev/urandom | od -An -t x | tr -d ' '

创建 token.csv,格式:token,用户,UID,用户组
▲滑动查看更多
<3> 创建kube-apiserver配置文件:kube-apiserver.conf
kube-apiserver有很多配置项,可以参考官方文档查看每个配置项的用途:
(注意:“\” 后面不要有空格,不要有多余的换行,否则启动失败)
▲滑动查看更多
重点配置说明:
--etcd-servers:etcd 集群地址
--bind-address:apiserver 监听的地址,一般配主机IP
--secure-port:监听的端口
--advertise-address:集群通告地址,其它Node节点通过这个地址连接 apiserver,不配置则使用bind-address
--service-cluster-ip-range:Service 的 虚拟IP范围,以CIDR格式标识,该IP范围不能与物理机的真实IP段有重合。
--service-node-port-range:Service 可映射的物理机端口范围,默认30000-32767
--admission-control:集群的准入控制设置,各控制模块以插件的形式依次生效,启用RBAC授权和节点自管理。
--authorization-mode:授权模式,包括:AlwaysAllow,AlwaysDeny,ABAC(基于属性的访问控制),Webhook,RBAC(基于角色的访问控制),Node(专门授权由 kubelet 发出的API请求)。(默认值"AlwaysAllow")。
--enable-bootstrap-token-auth:启用TLS bootstrap功能
--token-auth-file:这个文件将被用于通过令牌认证来保护API服务的安全端口。
--v:指定日志级别,0~8,越大日志越详细
<4> 创建apiserver服务:kube-apiserver.service
▲滑动查看更多
<5> 启动kube-apiserver组件
启动组件
# systemctl daemon-reload
# systemctl start kube-apiserver
# systemctl enable kube-apiserver
检查启动状态
# systemctl status kube-apiserver
查看启动日志
# less /k8s/kubernetes/logs/kube-apiserver.INFO
<6> 将kubelet-bootstrap用户绑定到系统集群角色,之后便于Node使用token请求证书:
▲滑动查看更多
4.3
部署kube-controller-manager组件
# cat > /k8s/kubernetes/cfg/kube-controller-manager.conf <<'EOF'
KUBE_CONTROLLER_MANAGER_OPTS="--leader-elect=true \
--master=127.0.0.1:8080 \
--address=127.0.0.1 \
--allocate-node-cidrs=true \
--cluster-cidr=10.244.0.0/16 \
--service-cluster-ip-range=10.0.0.0/24 \
--cluster-signing-cert-file=/k8s/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/k8s/kubernetes/ssl/ca-key.pem \
--root-ca-file=/k8s/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/k8s/kubernetes/ssl/ca-key.pem \
--experimental-cluster-signing-duration=87600h0m0s \
--v=2 \
--logtostderr=false \
—log-dir=/k8s/kubernetes/logs"
EOF
▲滑动查看更多
启动组件
# systemctl daemon-reload
# systemctl start kube-controller-manager
# systemctl enable kube-controller-manager
检查启动状态
# systemctl status kube-controller-manager
查看启动日志
# less /k8s/kubernetes/logs/kube-controller-manager.INFO
4.4
部署kube-scheduler组件
<1> 创建kube-scheduler配置文件:kube-scheduler.conf
# cat > /k8s/kubernetes/cfg/kube-scheduler.conf <<'EOF'
KUBE_SCHEDULER_OPTS="--leader-elect=true \
--master=127.0.0.1:8080 \
--address=127.0.0.1 \
--v=2 \
--logtostderr=false \
--log-dir=/k8s/kubernetes/logs"
EOF
<2> 创建 kube-scheduler服务:kube-scheduler.service
▲滑动查看更多
<3> 启动kube-scheduler组件
启动组件
# systemctl daemon-reload
# systemctl start kube-scheduler
# systemctl enable kube-scheduler
查看启动状态
# systemctl status kube-scheduler
查看启动日志
# less /k8s/kubernetes/logs/kube-scheduler.INFO
4.5
查看集群状态
<1> 查看组件状态
# kubectl get cs

05
Node节点部署
5.1
iSulad容器
iSula容器介绍参考iSulad在openEuler社区的SIG组:
https://gitee.com/openeuler/iSulad
<1> 安装iSula容器
#dnf install iSulad
<2> 修改iSulad配置文件
# vi /etc/isulad/daemon.json

(注意:树莓派是arm64架构,pause镜像需要使用arm64版本)
<3> 启动iSulad 服务
# systemctl start isulad
<4> 设置开机启动
# systemctl enable isulad
<5> 验证安装是否成功
# isula --version
# isula info
5.2
Node节点证书
<1> 创建Node节点的证书签名请求文件:kube-proxy-csr.json
首先在k8s-master2节点上,通过颁发的CA证书先创建好Node节点要使用的证书,先创建证书签名请求文件:kube-proxy-csr.json:
# cat > kube-proxy-csr.json <<EOF
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "kubernetes",
"OU": "System"
}
]
}
EOF
<2> 为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
<3> node节点创建工作目录
# mkdir -p /k8s/kubernetes/{bin,cfg,logs,ssl}
<4> 将k8s-master2节点的文件拷贝到node节点
将kubelet、kube-proxy拷贝到node节点上:
▲滑动查看更多
将证书拷贝到k8s-node1节点上:
# scp -r /k8s/kubernetes/ssl/{ca.pem,kube-proxy.pem,kube-proxy-key.pem} root@k8s-node1:/k8s/kubernetes/ssl/
5.3
安装kubelet
<1> 创建请求证书的配置文件:bootstrap.kubeconfig
bootstrap.kubeconfig将用于向apiserver请求证书,apiserver会验证token、证书 是否有效,验证通过则自动颁发证书。
▲滑动查看更多
说明:
certificate-authority:CA证书
server:master地址
token:master上token.csv中配置的token
<2> 创建kubelet 配置文件:kubelet-config.yml
为了安全性,kubelet禁止匿名访问,必须授权才可以,通过kubelet-config.yml授权 apiserver访问kubelet。
# cat > /k8s/kubernetes/cfg/kubelet-config.yml <<'EOF'
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /k8s/kubernetes/ssl/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthroizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 100000
maxPods: 110
EOF
说明:
address:kubelet监听地址
port:kubelet的端口
cgroupDriver:cgroup 驱动,与docker的cgroup驱动一致
authentication:访问kubelet的授权信息
authorization:认证相关信息
evictionHard:垃圾回收策略
maxPods:最大pod数
<3> 创建kubelet服务配置文件:kubelet.conf
▲滑动查看更多
说明:
--hostname-override:当前节点注册到k8s中显示的名称,默认为主机 hostname
--network-plugin:启用CNI网络插件
--cni-bin-dir:CNI插件可执行文件位置,默认在/opt/cni/bin下
--cni-conf-dir:CNI插件配置文件位置,默认在/etc/cni/net.d下
--cgroups-per-qos:必须加上这个参数和 --enforce-node-allocatable,否则报错 [Failed to start ContainerManager failed to initialize top level QOS containers.......]
--kubeconfig:会自动生成kubelet.kubeconfig,用于连接 apiserver
--bootstrap-kubeconfig:指定 bootstrap.kubeconfig 文件
--config:kubelet 配置文件
--cert-dir:证书目录
--pod-infra-container-image:管理Pod网络的镜像,基础的Pause容器,默认是 k8s.gcr.io/pause:3.1
★ 通过红框内的配置将runtime改为isula容器,默认是docker容器。

<4> 创建kubelet服务:kubelet.service
▲滑动查看更多
<5> 启动kubelet
# systemctl daemon-reload
# systemctl start kubelet
开机启动:
# systemctl enable kubelet
查看启动日志:
# tail -f /k8s/kubernetes/logs/kubelet.INFO
<6> master给 node授权
kubelet启动后还没加入到集群中,会向apiserver请求证书,需手动在k8s-master2 上对node授权。通过如下命令查看是否有新的客户端请求颁发证书:
# kubectl get csr

给客户端颁发证书,允许客户端加入集群:
▲滑动查看更多

<7> 授权成功
查看node是否加入集群:
# kubectl get node

颁发证书后,可以在 /k8s/kubenetes/ssl下看到master为kubelet颁发的证书:

在/k8s/kubenetes/cfg下可以看到自动生成的 kubelet.kubeconfig 配置文件:

5.4
安装 kube-proxy
<1> 创建kube-proxy连接apiserver的配置文件:kube-proxy.kubeconfig
# cat > /k8s/kubernetes/cfg/kube-proxy.kubeconfig <<'EOF'
apiVersion: v1
clusters:
- cluster:
certificate-authority: /k8s/kubernetes/ssl/ca.pem
server: https://192.168.1.2:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kube-proxy
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kube-proxy
user:
client-certificate: /k8s/kubernetes/ssl/kube-proxy.pem
client-key: /k8s/kubernetes/ssl/kube-proxy-key.pem
EOF
<2> 创建kube-proxy配置文件:kube-proxy-config.yml
# cat > /k8s/kubernetes/cfg/kube-proxy-config.yml <<'EOF'
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
address: 0.0.0.0
metrisBindAddress: 0.0.0.0:10249
clientConnection:
kubeconfig: /k8s/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-node1
clusterCIDR: 10.0.0.0/24
mode: ipvs
ipvs:
scheduler: "rr"
iptables:
masqueradeAll: true
EOF
说明:
metrisBindAddress:采集指标暴露的地址端口,便于监控系统,采集数据
clusterCIDR:集群Service网段
<3> 创建kube-proxy配置文件:kube-proxy.conf
# cat > /k8s/kubernetes/cfg/kube-proxy.conf <<'EOF'
KUBE_PROXY_OPTS="--config=/k8s/kubernetes/cfg/kube-proxy-config.yml \
--v=2 \
--logtostderr=false \
--log-dir=/k8s/kubernetes/logs"
EOF
<4> 创建 kube-proxy 服务:kube-proxy.service
▲滑动查看更多
<5> 启动kube-proxy
启动服务:
# systemctl daemon-reload
# systemctl start kube-proxy
开机启动:
# systemctl enable kube-proxy
查看启动日志:
# tail -f /k8s/kubernetes/logs/kube-proxy.INFO
5.5
部署其它Node节点
部署其它Node节点基于与上述流程一致,只需将配置文件中k8s-node1改为k8s-node2即可。
# kubectl get node -o wide

06
部署K8S容器集群网络(Flannel)
<1> K8S集群网络
Kubernetes项目并没有使用Docker的网络模型,kubernetes是通过一个CNI接口维护一个单独的网桥来代替 docker0,这个网桥默认叫cni0。
CNI(Container Network Interface)是CNCF旗下的一个项目,由一组用于配置 Linux 容器的网络接口的规范和库组成,同时还包含了一些插件。CNI仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。
Flannel是CNI的一个插件,可以看做是CNI接口的一种实现。Flannel是针对 Kubernetes设计的一个网络规划服务,它的功能是让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
通过给kubelet传递--network-plugin=cni命令行选项来启用CNI插件。kubelet从--cni-conf-dir(默认是/etc/cni/net.d)读取配置文件并使用该文件中的CNI配置来设置每个pod的网络。CNI配置文件必须与CNI规约匹配,并且配置引用的任何所需的 CNI 插件都必须存在于--cni-bin-dir(默认是/opt/cni/bin)指定的目录。
首先在node节点上创建两个目录:
# mkdir -p /opt/cni/bin /etc/cni/net.d
<3> 装 CNI 插件
可以从 github 上下载 CNI 插件:下载 CNI 插件 。
▲滑动查看更多

<4> 部署flannel
下载 flannel配置文件kube-flannel.yml:
▲滑动查看更多
如果无法解析raw.githubusercontent.com,在/etc/hosts中添加:
199.232.68.133 raw.githubusercontent.com
注意kube-flannel.yml中:Network的地址需与kube-controller-manager.conf中的--cluster-cidr=10.244.0.0/16保持一致。

在k8s-master2节点上部署 Flannel:
# kubectl apply -f kube-flannel.yml

<5> 检查部署状态
Flannel会在Node上起一个Pod,可以查看pod的状态看flannel是否启动成功:
# kubectl get pods -n kube-system -o wide

Flannel部署成功后,就可以看Node是否就绪:
# kubectl get nodes -o wide

在Node上查看网络配置,可以看到多了一个flannel.1 的虚拟网卡,这块网卡用于接收 Pod 的流量并转发出去。

<6> 测试创建pod
创建一个nginx服务:
# cat > nginx.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx0-deployment
labels:
app: nginx0-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx0
template:
metadata:
labels:
app: nginx0
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx:1.7.9
ports:
- containerPort: 80
EOF
# kubectl apply -f nginx.yaml

07
部署dashboard
k8s提供了一个 Web版Dashboard,用户可以用dashboard部署容器化的应用、监控应用的状态,能够创建和修改各种K8S资源,比如Deployment、Job、DaemonSet等。用户可以Scale Up/Down Deployment、执行 Rolling Update、重启某个Pod或者通过向导部署新的应用。Dashboard能显示集群中各种资源的状态以及日志信息。Dashboard提供了 kubectl的绝大部分功能。
<1> 下载dashboard配置文件
▲滑动查看更多
<2> 修改配置文件通,过Node暴露端口访问dashboard

<3> 部署dashboard
# kubectl apply -f dashboard.yaml
查看是否部署成功:
# kubectl get pods,svc -n kubernetes-dashboard

通过https访问dashboard:
地址为集群中任意node节点地址加上上面红框中的端口30005:https://192.168.1.4:30005

<4> 登录授权
Dashboard支持Kubeconfig和Token两种认证方式,为了简化配置,我们通过配置文件为Dashboard默认用户赋予admin权限。
# cat > kubernetes-adminuser.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
EOF
授权:
# kubectl apply -f kubernetes-adminuser.yaml

获取登录的 token:
# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk ' {print $1}')

通过token登录进 dashboard,就可以查看集群的信息:

08
多Master部署
<1> 将k8s-master2上相关文件拷贝到k8s-master1和k8s-master3上
在k8s-master1和k8s-master3上创建k8s工作目录:
# mkdir -p /k8s/kubernetes
# mkdir -p /k8s/etcd
拷贝k8s配置文件、执行文件、证书:
# scp -r /k8s/kubernetes/{cfg,ssl,bin} root@k8s-master1:/k8s/kubernetes
# cp /k8s/kubernetes/bin/kubectl /usr/local/bin/
拷贝 etcd 证书:
# scp -r /k8s/etcd/ssl root@k8s-master1:/k8s/etcd
拷贝 k8s 服务的service文件:
# scp /usr/lib/systemd/system/kube-* root@k8s-master1:/usr/lib/systemd/system
<2> 修改kube-apiserver配置文件
修改kube-apiserver.conf,修改IP为本机IP。
k8s-master1:

k8s-master3:

<3> 启动k8s-master1和k8s-master3组件
重新加载配置:
# systemctl daemon-reload
启动 kube-apiserver:
# systemctl start kube-apiserver
# systemctl enable kube-apiserver
启动 kube-controller-manager:
# systemctl start kube-controller-manager
# systemctl enable kube-controller-manager
部署 kube-scheduler:
# systemctl start kube-scheduler
# systemctl enable kube-scheduler
<4> 验证

至此,k8s集群部署完成。
09
一些小技巧
1) etcd更改配置后下次启动还是旧的配置
etcd数据存储目录由配置文件中的ETCD_DATA_DIR指定,删除该目录下的文件即可。

2) 每次开机初始化及清理历史数据操作较多
可以将这些操作封装在脚本中,一键执行。

3) 树莓派如果无法访问境外仓库,可以先通过境外服务器下载需要的容器镜像,然后通过isula的save、load、tag操作将镜像存储在本地。
注意,可以更改服务yaml配置,将镜像下载策略改为优先使用本地镜像:

4) 在图示路径添加网卡配置文件,树莓派开机即可获得固定IP地址。

版权声明:
本次部署实践及本操作指导均参考:
https://www.cnblogs.com/chiangchou/p/k8s-1.html#_label5
权侵删


本文分享自微信公众号 - openEuler(openEulercommunity)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。