如何在openEuler树莓派镜像上部署k8s+iSula集群(下篇)
续:如何在openEuler树莓派镜像上部署k8s+iSula集群(上篇)
05Node节点部署
5.1iSulad容器
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.2Node节点证书
<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节点上:
# scp -r /usr/local/src/kubernetes/server/bin/{kubelet,kube-proxy} root@k8s-node1:/k8s/kubernetes/bin/
将证书拷贝到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、证书 是否有效,验证通过则自动颁发证书。
# cat > /k8s/kubernetes/cfg/bootstrap.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: kubelet-bootstrap
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kubelet-bootstrap
user:
token: 0bd319ce03411f546841d74397b1d778
EOF
说明:
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
# cat > /k8s/kubernetes/cfg/kubelet.conf <<'EOF'
KUBELET_OPTS="--hostname-override=k8s-node1 \
--container-runtime=remote \
--container-runtime-endpoint=/var/run/isulad.sock \
--network-plugin=cni \
--cni-bin-dir=/opt/cni/bin \
--cni-conf-dir=/etc/cni/net.d \
--cgroups-per-qos=false \
--enforce-node-allocatable="" \
--kubeconfig=/k8s/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/k8s/kubernetes/cfg/bootstrap.kubeconfig \
--config=/k8s/kubernetes/cfg/kubelet-config.yml \
--cert-dir=/k8s/kubernetes/ssl \
--pod-infra-container-image=kubernetes/pause:latest \
--v=2 \
--logtostderr=false \
—log-dir=/k8s/kubernetes/logs"
EOF
说明:
--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
# cat > /usr/lib/systemd/system/kubelet.service <<'EOF'
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Before=docker.service
[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kubelet.conf
ExecStart=/k8s/kubernetes/bin/kubelet $KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
<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
给客户端颁发证书,允许客户端加入集群:
# kubectl certificate approve node-csr- node-csr-y2FJp1MtFFoPBv0e_4pLYECYD889rQuTIAnu1EuXtjU
<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
# kubectl certificate
# cat > /usr/lib/systemd/system/kube-proxy.service <<'EOF'
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kube-proxy.conf
ExecStart=/k8s/kubernetes/bin/kube-proxy $KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
<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通信。
<2> 创建CNI工作目录
通过给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 插件 。
# curl -L https://github.com/containernetworking/plugins/releases/download/v0.8.7/cni-plugins-linux-arm64-v0.8.7.tgz | tar -C /opt/cni/bin -xz
<4> 部署flannel
下载 flannel配置文件kube-flannel.yml:
# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/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配置文件
# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml.yml
将recommended.yaml重命名为dashboard.yaml
<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