因为资源有限只是用了1master ,2node部署,分别部署在阿里云、腾讯云和华为云ecs上。
root@master ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
配置均为 2核 CPU 4G 内存
一、kubernets原理架构简介
“隔离” 应该是今年的一大热词了,百度下下面都是相关疫情隔离的条目,可以看隔离是非常的立体的,从居家隔离,到小区隔离,区县社区、再到省市间限制,到处是体温检测点。这些隔离是为了安全,但是我们还要生活还可以组织,进行一些远程工作。比如我们社区留个门,一个检查点,设置出入证等。这些其实都是需要通过管理,还有物流和网络等技术让大家保持运作。
docker的核心基础其实也是隔离,虽然是基于虚拟的但也需要同样协同运作。应该注意docker其实是容器的一种,还有很多容器比如containerd、lxc 、pouch和kata等。所以更确切的说,容器是只是中文上比较形象的理解,从开源技术上应该是一种runtime,只是docker已经更为流行形成了一个规范罢了。
而我们知道swarm是docker的编排工具,这就是是起到了容器运行,重启、协调、分布式、负载均衡等等问题。而docker-compose就是一种抽象的编排部署,把相关的容器关联起来,但是它是在一个服务器上的,如果跨服务器就需要swarm了,类似我们组成了个虚拟团队或是远程协同办公。swarm虽然简单,方便,但是还有很多不足,所以现在行业更多使用的就是kubernets
,也是个容器编排工具,而且kubernets理论上可以跑除了docker的其它容器。就比如我们有考试服务、日志服务、电商服务和数据服务等,虽然各处几个服务器上,但是还是相关的联系起来提供服务。它有更丰富的管理工具集,所以kubernets的协同管理更加完善,这也是大家选择它的主要原因。
选择k8s的优势有:
- 服务的可用性高,容器自动组装、自动部署;
- 容器或服务器挂了后会自我修复,重启,比swarm自动化程度高
3.自动水平扩展,服务发现,负载均衡;
4.支持密钥和配置管理,能将服务的配置通过服务来加载,而不用本地配置,保证了配置的一致性。
5.有配套的面板,可操作性好
6.较好存储编排和任务批处理
这些特性字面看比较抽象干涩,所以还是从它的物理和逻辑架构和原理上来一一了解。
首先是基本概念
k8s的组成更多,甚至有比较抽象的概念比如pod
Pods
Pods是k8s操作的最小单元,从这个层面理解上看,确实k8s是更大的集合,它不仅可以跑docker容器,也可以是其它容器。相对来说,Pods这里就是比较抽象的了,因为实际上机器上运行的还是个runtime。Pods是更好组织的一个抽象,所以从英文名也可以看出,它叫吊舱,用来放集装箱的。
另外作为最小的运行单元,也增加了面向业务的抽象理解,一个业务可以是多个容器运行,而对于这组容器在k8s里可以看做一个Pod。
接下来是比较容易理解的物理层的概念了,master和nodeMaster:
集群的主要控制节点,负责集群的总体控制,一些我们需要操作的命令都是在master上操作。生产上一般部署双节点保证安全性,资源有限就部署一个可以运行。
master上有几个主要组件,也是管理进程
- Kubernetes API Server(kube-apiserver), 提供 HTTP Rest ful接口的关键服务程序,kubernets里所有资源增、删、改、查等操作的唯一入口,也是集群控制的入口进程,所有操作都会经过它后存到etcd。
- Kubernetes Controller Manager(kube-controller-manager),所有资源对象的自动化控制中心(资源对象的大总管),如果说kube-apiserver是前台交互的接口,那么kube-controller-manager就是真正后面的控制器,对各个资源进行操作。
- Kubernetes Scheduler(kube-scheduler),资源调度(pod)的进程(调度室),就是把Pod分配到合适的node上。
- etcd Server,Kubernetes 里所有资源对象的数据全部是保持在etcd中,这只是用了存储,类似redis的k-v存储,这个可以是在master上但一般是集群高可用,以3以上的奇数个节点分布式部署,所以是公共组件。-
Node:
就是真正工作的服务器节点,可以使用物理机或虚拟机运行,node主要上有kubelet、kube-proxy当然还有runtime (比如docker engine)等组件。- kubelet ,Kubelet是Master在每个Node节点上面的agent,真正执行在node上的容器增加、删除等。
- kube-proxy: 主要负责Kubernetes中的服务发现和反向代理功能。
ReplicationController:
RC是早期的资源管理抽象,kubelet是管理自己节点上的Pod,那节点挂了这时候上面的pods就失联了,所以需要更高级的集群级的虚拟资源管理。从其名称副本控制器也可以知道,它是Pod容器扩缩容的主要管理者,RC通过复制机制管理容器,如果有镜像则复制产生容器,如果没有就拉取镜像,再根据设置创建副本。ReplicationSet:
ReplicationSet的行为和ReplicationController完全相同,但是Pod选择器的表达能力更强。ReplicationController只允许包含某个标签的匹配,ReplicationSet还允许缺失某个标签的匹配,标签多个值的匹配等等。所以RS比RC更强大,可以是RC的替代者。Deployment:
1.2提出的,就是ReplicationSet的管理者,它可以实时知道Pods的部署进度。service:
容器服务的抽象概念,Pods 的独立 IP 通过端口映射成一个 Service 向网络外提供服务。Volume :
Pod中能够被多个容器访问的共享目录,其生命周期与Pod相同跟容器无关,类似docker的存储卷。-
网络组件:
一般是用软件定义网络,实现master和nodes间的通信,默认是flannel overlay,还有calico ,weave等可选择。
二、kubernets部署方式
- Minikube,一个小型kubernets安装部署工具,适合本地开发测试,可以快速部署一个单节点集群,适合测试开发环境。
- Kubeadm,这是kubernets官方推荐的安装工具集,也是最佳实践,类似swarm 可以有init ,join等操作,操作方便。但是不大推荐生产环境。
- 二进制部署,就是下载上面需要组件的二进制包到master和node节点安装,比较麻烦,但是安全可靠,适合生产环境。同时也有助于学习kubernets架构。
三、kubernets集群部署
环境准备
修改主机名
#master节点:
hostnamectl set-hostname master
#node0节点:
hostnamectl set-hostname huawei
#node1节点:
hostnamectl set-hostname tencent
修改/etc/hosts文件 ,增加各个节点对应ip和名称
基础软件安装
各个机器都要做的
关闭防火墙和selinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0
关闭swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
配置时间同步
使用chrony同步时间,配置master节点与网络NTP服务器同步时间,所有node节点与master节点同步时间。
配置master节点:
安装chrony:
yum install -y chrony
注释默认ntp服务器
sed -i 's/^server/#&/' /etc/chrony.conf
指定上游公共 ntp 服务器,并允许其他节点同步时间
cat >> /etc/chrony.conf << EOF
server 0.asia.pool.ntp.org iburst
server 1.asia.pool.ntp.org iburst
server 2.asia.pool.ntp.org iburst
server 3.asia.pool.ntp.org iburst
allow all
EOF
重启chronyd服务并设为开机启动:
systemctl enable chronyd && systemctl restart chronyd
开启网络时间同步功能
timedatectl set-ntp true
配置所有node节点:
(注意修改master IP地址)
安装chrony:
yum install -y chrony
注释默认服务器
sed -i 's/^server/#&/' /etc/chrony.conf
指定内网 master节点为上游NTP服务器
echo server 120.24.197.36 iburst >> /etc/chrony.conf
重启服务并设为开机启动:
systemctl enable chronyd && systemctl restart chronyd
所有节点执行chronyc sources命令,查看存在以^*开头的行,说明已经与服务器时间同步
设置网桥包经过iptables
RHEL / CentOS 7上的一些用户报告了由于iptables被绕过而导致流量路由不正确的问题。创建/etc/sysctl.d/k8s.conf文件,添加如下内容:
cat < /etc/sysctl.d/k8s.conf
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
使配置生效
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
官网下载kubernetes v1.13.0 二进制包,
下载完成后,上传到服务器:
kubernetes-server-linux-amd64.tar.gz上传到master节点。
kubernetes-node-linux-amd64.tar.gz 上传到node节点。
[root@master ~]# wget https://storage.googleapis.com/kubernetes-release/release/v1.13.0/kubernetes-server-linux-amd64.tar.gz
[root@node0 ~]# wget [https://storage.googleapis.com/kubernetes-release/release/v1.13.0/kubernetes-node-linux-amd64.tar.gz](https://storage.googleapis.com/kubernetes-release/release/v1.13.0/kubernetes-node-linux-amd64.tar.gz)
[root@node0 ~]# wget [https://storage.googleapis.com/kubernetes-release/release/v1.13.0/kubernetes-node-linux-amd64.tar.gz](https://storage.googleapis.com/kubernetes-release/release/v1.13.0/kubernetes-node-linux-amd64.tar.gz)
测试客户端
[root@huaweitest ~]# wget https://dl.k8s.io/v1.13.0/kubernetes-client-linux-amd64.tar.gz
网络先选择flannel
flannel下载网址
https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
四、etcd集群部署
ca安全认证
自己部署安全高可用的kubernets最麻烦的是安全认证了,kubernets光通信需要5套证书
- etcd 内部通信需要一套证书。
- etcd 与外部通信需要一套证书。
- APIServer 间通讯需要一套证书。
- APIServer 与 Node 通信需要一套证书。
- Node 与 Node 间通信需要一套证书。
在master上 进行cfssl安装 ,之后传到其它节点
wget [https://pkg.cfssl.org/R1.2/cfssl_linux-amd64](https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
)
wget [https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64](https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
)
wget [https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64](https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
)
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
建立k8s文件夹
[root@master /]# mkdir /k8s/etcd/{bin,cfg,ssl} -p
[root@master ~]# mkdir /k8s/kubernetes/{bin,cfg,ssl} -p
etcd证书
1)etcd ca配置
[root@master /]# cd /k8s/etcd/ssl
[root@master ssl]# cat << EOF | tee ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
2)etcd ca证书
[root@master ssl]# cat << EOF | tee ca-csr.json
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
3)etcd server证书
cat << EOF | tee server-csr.json
{
"CN": "etcd",
"hosts": [
"120.24.197.36",
"120.76.56.191",
"106.13.35.136",
"[114.116.85.168](https://console.huaweicloud.com/vpc/?agencyId=4b099fa1cc4541b297de0bc43e63b5b3®ion=cn-north-1&locale=zh-cn#/vpc/vpcmanager/eipDetailNew/eipBWDetail?eipId=d3e9cef8-0551-4f15-8c20-74fa50c62aee)",
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
4)生成etcd ca证书和私钥
初始化ca
[root@master ssl]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2019/01/30 16:03:06 [INFO] generating a new CA key and certificate from CSR
2019/01/30 16:03:06 [INFO] generate received request
2019/01/30 16:03:06 [INFO] received CSR
2019/01/30 16:03:06 [INFO] generating key: rsa-2048
2019/01/30 16:03:06 [INFO] encoded CSR
2019/01/30 16:03:06 [INFO] signed certificate with serial number 433764805398283651186930197738261863494647833559
生成server证书
[root@master ssl]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
2019/01/30 16:29:07 [INFO] generate received request
2019/01/30 16:29:07 [INFO] received CSR
2019/01/30 16:29:07 [INFO] generating key: rsa-2048
2019/01/30 16:29:07 [INFO] encoded CSR
2019/01/30 16:29:07 [INFO] signed certificate with serial number 131821190969284385544659569208505477288538494680
2019/01/30 16:29:07 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
分发给各个节点
[root@master ssl]# scp ./* 114.116.85.168:/k8s/etcd/ssl/
docker部署etcd集群
这里测试方便用docker一键部署,当然一般是用二进制
#编写docker-compose编排文件
[root@node0 etcd]# cat /opt/etcd/docker-compose.yaml
version: '3'
services:
etcd:
container_name: etcd
image: quay.io/coreos/etcd:v3.3.2
ports:
- "2379:2379"
- "2380:2380"
- "4001:4001"
volumes:
- "/k8s/etcd/ssl:/etc/ssl/certs"
environment:
- host_ip=120.76.56.191
command:
/usr/local/bin/etcd
-name etcd1
-cert-file /etc/ssl/certs/server.pem
-key-file /etc/ssl/certs/server-key.pem
-trusted-ca-file /etc/ssl/certs/ca.pem
-client-cert-auth "true"
-peer-cert-file /etc/ssl/certs/server.pem
-peer-key-file /etc/ssl/certs/server-key.pem
-peer-trusted-ca-file /etc/ssl/certs/ca.pem
-peer-client-cert-auth "true"
-advertise-client-urls https://120.76.56.191:2379,https://120.76.56.191:4001
-listen-client-urls https://0.0.0.0:2379,https://0.0.0.0:4001
-initial-advertise-peer-urls https://120.76.56.191:2380
-listen-peer-urls https://0.0.0.0:2380
-initial-cluster-token etcd-cluster-1
-initial-cluster etcd0=https://120.24.197.36:2380,etcd1=https://120.76.56.191:2380,etcd2=https://106.13.35.136:2380,etcd3=https://114.116.85.168:2380
-initial-cluster-state new
#启动第一个节点
[root@master etcd]# docker-compose up -d
#查看节点运行状态
[root@master etcd]# docker exec -it etcd etcdctl member list
client: etcd cluster is unavailable or misconfigured; error #0: client: endpoint http://127.0.0.1:4001 exceeded header timeout
; error #1: client: endpoint http://127.0.0.1:2379 exceeded header timeout
[root@master etcd]# docker exec -it etcd etcdctl cluster-health
cluster may be unhealthy: failed to list members
Error: client: etcd cluster is unavailable or misconfigured; error #0: client: endpoint http://127.0.0.1:2379 exceeded header timeout
; error #1: client: endpoint http://127.0.0.1:4001 exceeded header timeout
error #0: client: endpoint http://127.0.0.1:2379 exceeded header timeout
error #1: client: endpoint http://127.0.0.1:4001 exceeded header timeout
#启动其它机器上的etcd进程
#验证集群状态,这时候需要使用到认证来访问
etcdctl --ca-file=/etc/ssl/certs/ca.pem \
--cert-file=/etc/ssl/certs/server.pem \
--key-file=/etc/ssl/certs/server-key.pem \
--endpoints="https://120.24.197.36:2379,https://120.76.56.191:2379,https://106\
.13.35.136:2379,https://114.116.85.168:2379" \
cluster-health
member 246aed1b1dea022e is healthy: got healthy result from https://120.24.197.36:2379
member 38c6fad5d8e69fa1 is healthy: got healthy result from https://120.76.56.191:2379
member 63d1c9a736e8760f is healthy: got healthy result from https://114.116.85.168:2379
member 7db4113957e69f8c is healthy: got healthy result from https://106.13.35.136:2379
cluster is healthy
#集群正常,也可以用docker查看
[root@master etcd]# docker exec -it etcd etcdctl --ca-file=/etc/ssl/certs/ca.pem --cert-file=/etc/ssl/certs/server.pem --key-file=/etc/ssl/certs/server-key.pem --endpoints="https://120.24.197.36:2379,https://120.76.56.191:2379,https://106.13.35.136:2379,https://114.116.85.168:2379" cluster-health
member 246aed1b1dea022e is healthy: got healthy result from https://120.24.197.36:2379
member 38c6fad5d8e69fa1 is healthy: got healthy result from https://120.76.56.191:2379
member 63d1c9a736e8760f is healthy: got healthy result from https://114.116.85.168:2379
member 7db4113957e69f8c is healthy: got healthy result from https://106.13.35.136:2379
cluster is healthy
制作其它证书与私钥
制作kubernetes ca证书
cd /k8s/kubernetes/ssl
cat << EOF | tee ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cat << EOF | tee ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
[root@master ssl] cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
制作apiserver证书
cat << EOF | tee server-csr.json
{
"CN": "kubernetes",
"hosts": [
"120.24.197.36",
"127.0.0.1",
"10.0.0.1",
"120.76.56.191",
"106.13.35.136",
"[114.116.85.168](https://console.huaweicloud.com/vpc/?agencyId=4b099fa1cc4541b297de0bc43e63b5b3®ion=cn-north-1&locale=zh-cn#/vpc/vpcmanager/eipDetailNew/eipBWDetail?eipId=d3e9cef8-0551-4f15-8c20-74fa50c62aee)",
"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"
}
]
}
EOF
[root@master ssl] cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
制作kube-proxy证书
cat << EOF | tee 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"
}
]
}
EOF
[root@master ssl] cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
mater节点部署
kubernetes master 节点运行如下组件:
kube-apiserver
kube-scheduler
kube-controller-manager
kube-scheduler 和 kube-controller-manager 可以以集群模式运行,通过 leader 选举产生一个工作进程,其它进程处于阻塞模式,master三节点高可用模式下可用
1.首先到kubernetes官网找到相应的二进制包
cd /usr/local/src/
wget [https://dl.k8s.io/v1.11.0/kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.11.0/kubernetes-server-linux-amd64.tar.gz)
wget [https://dl.k8s.io/v1.12.0/kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.11.0/kubernetes-server-linux-amd64.tar.gz)
2.解压kubernetes-server-linux-amd64.tar.gz
tar -zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin & ls
3.将kube-apiserver,kube-controller-manager,kube-scheduler复制到k8s目录下
[root@master bin]# cp kube-scheduler kube-apiserver kube-controller-manager kubectl /k8s/kubernetes/bin/
部署kube-apiserver组件
创建TLS Bootstrapping Token
[root@master bin]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '
d51a20d30503be51aabd7e53aadc2028
[root@master bin]# vim /k8s/kubernetes/cfg/token.csv
d51a20d30503be51aabd7e53aadc2028,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
创建Apiserver配置文件
vim /k8s/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=true \
--v=4 \
--etcd-servers=https://120.24.197.36:2379,https://120.76.56.191:2379,https://106.13.35.136:2379,https://114.116.85.168:2379 \
--bind-address=120.24.197.36 \
--secure-port=6443 \
--insecure-port=8081 \
--advertise-address=120.24.197.36 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/16 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth \
--token-auth-file=/k8s/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/k8s/kubernetes/ssl/server.pem \
--tls-private-key-file=/k8s/kubernetes/ssl/server-key.pem \
--client-ca-file=/k8s/kubernetes/ssl/ca.pem \
--service-account-key-file=/k8s/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/k8s/etcd/ssl/ca.pem \
--etcd-certfile=/k8s/etcd/ssl/server.pem \
--etcd-keyfile=/k8s/etcd/ssl/server-key.pem"
# 启用日志标准错误
KUBE_LOGTOSTDERR="--logtostderr=true"
# 日志级别
KUBE_LOG_LEVEL="--v=4"
# Etcd服务地址
KUBE_ETCD_SERVERS="--etcd-servers=http://120.24.197.36:2379"
# API服务监听地址
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
# API服务监听端口
KUBE_API_PORT="--insecure-port=8081" #这里默认是8080 ,改为8081
服务的Ports和IPs
Kubernets API Server进程提供Kuvernetes API。通常情况下,有一个进程运行在单一kubernetes-master节点上。
默认情况,Kubernetes API Server提供HTTP的两个端口:
1.本地主机端口
HTTP服务
默认端口8080,修改标识–insecure-port
默认IP是本地主机,修改标识—insecure-bind-address
在HTTP中没有认证和授权检查
主机访问受保护
2.Secure Port
默认端口6443,修改标识—secure-port
默认IP是首个非本地主机的网络接口,修改标识—bind-address
HTTPS服务。设置证书和秘钥的标识,–tls-cert-file,–tls-private-key-file
认证方式,令牌文件或者客户端证书
使用基于策略的授权方式
# 对集群中成员提供API服务地址
KUBE_ADVERTISE_ADDR="--advertise-address=120.24.197.36"
# 允许容器请求特权模式,默认false
KUBE_ALLOW_PRIV="--allow-privileged=false"
# 集群分配的IP范围
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.10.10.0/16"
创建apiserver systemd文件
5.设置systemd服务文件/usr/lib/systemd/system/kube-apiserver.service
[root@master bin]# vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/k8s/kubernetes/cfg/kube-apiserver
ExecStart=/k8s/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
启动服务,并设置开机启动:
[root@master ~]# vim /k8s/kubernetes/cfg/kube-apiserver
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart kube-apiserver
[root@master ~]# systemctl status kube-apiserver
● kube-apiserver.service - Kubernetes API Server
Loaded: loaded (/usr/lib/systemd/system/kube-apiserver.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2019-01-31 23:37:36 CST; 3ms ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 26315 (kube-apiserver)
Tasks: 1
Memory: 120.0K
CGroup: /system.slice/kube-apiserver.service
└─26315 /k8s/kubernetes/bin/kube-apiserver --logtostderr=true --v=4 --etcd-servers=https://120.24.197.36:2379,https://120.76.56.191:2379,https://106.13.35.136:2379,https://114...
Jan 31 23:37:36 master systemd[1]: Started Kubernetes API Server.
可以看到两个监听地址端口
[root@master ~]# netstat -tulpn |grep kube-apiserve
tcp 0 0 120.24.197.36:6443 0.0.0.0:* LISTEN 27203/kube-apiserve
tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 27203/kube-apiserve
注意:apiserver默认支持etcd3,如果是etcd2,需启动时指定版本选项--storage-backend=etcd2
安装kube-controller-manager
1.设置systemd服务文件/usr/lib/systemd/system/kube-controller-manager.service服务
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/k8s/kubernetes/cfg/kube-controller-manager
ExecStart=/k8s/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
2.编辑配置文件
[root@master ~] vim /k8s/kubernetes/cfg/kube-controller-manager
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=true \
--v=4 \
--master=127.0.0.1:8081 \
--leader-elect=true \
--address=127.0.0.1 \
--service-cluster-ip-range=10.0.0.0/16 \
--cluster-name=kubernetes \
--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"
部署安装kube-scheduler
1.设置systemd服务文件/usr/lib/systemd/system/kube-scheduler.service服务
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/k8s/kubernetes/cfg/kube-scheduler
ExecStart=/k8s/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
创建kube-scheduler配置文件
KUBE_SCHEDULER_OPTS="--master=https://127.0.0.1:8081 --logtostderr=true --log-dir=/var/log/kubernetes --v=2 --leader-elect"
参数备注:
--address:在 127.0.0.1:10251 端口接收 http /metrics 请求;kube-scheduler 目前还不支持接收 https 请求;
--kubeconfig:指定 kubeconfig 文件路径,kube-scheduler 使用它连接和验证 kube-apiserver;
--leader-elect=true:集群运行模式,启用选举功能;被选为 leader 的节点负责处理工作,其它节点为阻塞状态;
启动master各个服务
systemctl daemon-reload
systemctl enable kube-apiserver.service
systemctl start kube-apiserver.service
systemctl enable kube-controller-manager.service
systemctl start kube-controller-manager.service
systemctl enable kube-scheduler
systemctl start kube-scheduler
验证kubeserver服务
设置环境变量
vim /etc/profile
PATH=/k8s/kubernetes/bin:$PATH
source /etc/profile
查看master服务状态
kubectl get cs,nodes
[root@master bin] kubectl get cs,nodes
部署kubectl命令行工具(可选)
这是个可能碰到的坑,而且很多文章会省略这个,如果不使用默认端口8080,使用kubectl命令行工具就会报错
[root@master ~]# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?
kubectl 默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息,如果没有配置就会有上面的报错。
配置无机器无关,即集群所有使用kubectl的节点的这个配置文件是一样的,保存都是kube-apiserver的信息。我们只要制作一次分发到各个节点就可以。
首先创建admin证书和私钥
用户在终端输入命令行到kubectl,kubectl工具解析命令再发到apiserver的HTTPS安全通信端口,apiserver要对提供的安全证书认证授权,所以kubectl要被授予最高权限。这里使用admin权限。
[root@master ssl]# cat > admin-csr.json < {
> "CN": "admin",
> "hosts": [],
> "key": {
> "algo": "rsa",
> "size": 2048
> },
> "names": [
> {
> "C": "CN",
> "ST": "BeiJing",
> "L": "BeiJing",
> "O": "system:masters",
> "OU": "4Paradigm"
> }
> ]
> }
> EOF
O:请求权限组,这里为group system:masters
Hosts:该证书只会被kubectl当做client证书使用,所以hosts为空
预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予所有 API的权限;
制作证书和私钥
[root@master ssl]# cfssl gencert -ca=/k8s/kubernetes/ssl/ca.pem -ca-key=/k8s/kubernetes/ssl/ca-key.pem -config=/k8s/kubernetes/ssl/ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
2019/03/10 19:25:34 [INFO] generate received request
2019/03/10 19:25:34 [INFO] received CSR
2019/03/10 19:25:34 [INFO] generating key: rsa-2048
2019/03/10 19:25:34 [INFO] encoded CSR
2019/03/10 19:25:34 [INFO] signed certificate with serial number 404733632039314316714479304382575784121522879770
2019/03/10 19:25:34 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
创建 kubeconfig 文件
kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书;
[root@master ssl]# vim /k8s/kubernetes/bin/environment.sh
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/k8s/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubectl.kubeconfig
# 设置客户端认证参数
kubectl config set-credentials admin \
--client-certificate=admin.pem \
--client-key=admin-key.pem \
--embed-certs=true \
--kubeconfig=kubectl.kubeconfig
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=kubectl.kubeconfig
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
[root@master ssl]# source /k8s/kubernetes/bin/environment.sh
Cluster "kubernetes" set.
User "admin" set.
Context "kubernetes" created.
--certificate-authority:验证 kube-apiserver 证书的根证书;
--client-certificate、--client-key:刚生成的 admin 证书和私钥,连接 kube-apiserver 时使用;
--embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径);
保存kubectl.kubeconfg 到用户的 ~/.kube/config 文件
[root@master ssl]# mkdir ~/.kube
[root@master ssl]# cp kubectl.kubeconfig ~/.kube/config
分发到各个节点 (略)
[root@master ssl]# kubectl cluster-info
Kubernetes master is running at https://120.24.197.36:6443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@master ssl]# kubectl get cs
node节点部署
kubelet 组件部署
kublet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如exec、run、logs 等;
kublet 启动时自动向 kube-apiserver 注册节点信息,内置的 cadvisor 统计和监控节点的资源使用情况;
为确保安全,只开启接收 https 请求的安全端口,对请求进行认证和授权,拒绝未授权的访问(如apiserver、heapster)
1)安装二进制文件
tar zxvf kubernetes-node-linux-amd64.tar.gz
cd kubernetes/node/bin/
cp kube-proxy kubelet kubectl /k8s/kubernetes/bin/
[root@node1 ~]# mkdir -p /k8s/kubernetes/bin
[root@node1 ~]# cp kubernetes/node/bin/kube* /k8s/kubernetes/bin/
2)复制相关证书到node节点
建文件夹
[root@node0 bin]# mkdir -p /k8s/kubernetes/ssl
[root@node1 bin]# mkdir -p /k8s/kubernetes/ssl
[root@huaweitest bin]# mkdir -p /k8s/kubernetes/ssl
传输文件到各个节点
3)创建kubelet bootstrap kubeconfig文件
通过脚本实现
vim /k8s/kubernetes/cfg/environment.sh
#!/bin/bash
#创建kubelet bootstrapping kubeconfig
BOOTSTRAP_TOKEN=d51a20d30503be51aabd7e53aadc2028
KUBE_APISERVER="https://120.24.197.36:6443"
#设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/k8s/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
#设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_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
#----------------------
# 创建kube-proxy kubeconfig文件
kubectl config set-cluster kubernetes \
--certificate-authority=/k8s/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=/k8s/kubernetes/ssl/kube-proxy.pem \
--client-key=/k8s/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
[root@node0 cfg]# sh environment.sh
Cluster "kubernetes" set.
User "kubelet-bootstrap" set.
Context "default" created.
Switched to context "default".
Cluster "kubernetes" set.
User "kube-proxy" set.
Context "default" created.
Switched to context "default".
4)创建kubelet参数配置模板文件
[root@node0 cfg]# vim /k8s/kubernetes/cfg/kubelet.config
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 120.76.56.191
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS: ["10.0.0.10"]
clusterDomain: cluster.local.
failSwapOn: false
authentication:
anonymous:
enabled: true
5)创建kubelet配置文件
[root@node0 ~]# vim /k8s/kubernetes/cfg/kubelet
KUBELET_OPTS="--logtostderr=true \
--v=4 \
--hostname-override=120.76.56.191 \
--kubeconfig=/k8s/kubernetes/cfg/kubelet.kubeconfig \
--bootstrap-kubeconfig=/k8s/kubernetes/cfg/bootstrap.kubeconfig \
--config=/k8s/kubernetes/cfg/kubelet.config \
--cert-dir=/k8s/kubernetes/ssl \
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
6)创建kubelet systemd文件
[root@node0 ~]# vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/k8s/kubernetes/cfg/kubelet
ExecStart=/k8s/kubernetes/bin/kubelet $KUBELET_OPTS
Restart=on-failure
KillMode=process
[Install]
WantedBy=multi-user.target
7)将kubelet-bootstrap用户绑定到系统集群角色
可以在有kubectl命令行工具的master节点上操作,
[root@master ~]# kubectl create clusterrolebinding kubelet-bootstrap \
> --clusterrole=system:node-bootstrapper \
> --user=kubelet-bootstrap
clusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created
8)启动服务
[root@node0 ~]# systemctl daemon-reload
[root@node0 ~]# systemctl enable kubelet
[root@node0 ~]# systemctl start kubelet
查看节点
四、部署体验kuboard面板
安装Kuboard
外网可以直接部署,如果是内网则去官网找对应版本安装包
[root@master ~]# kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml
查看是否部署成功
[root@master ~]# kubectl get pods -l k8s.eip.work/name=kuboard -n kube-system
NAME READY STATUS RESTARTS AGE
kuboard-6ccc4747c4-h64d7 1/1 Running 0 105s
获取秘钥
[root@master kuboard]# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}')
登录验证
登录会有个输入框让输入秘钥,就是复制刚才获取的一长串,然后登录
五、测试部署docker微服务
这里用kubernets部署可道云做测试,只是单机测试,真正的状态存储肯定要有改进了。
从管理过程逻辑看,deployment管理各个ReplicaSet ,而ReplicaSet控制Pod,Pod里跑容器,这里是docker,而逻辑上通过service提供对外服务。
先创建 deployment 模版文件 kodexplorer-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kodexplorer-deployment
labels:
app: kodexplorer
spec:
replicas: 1
selector:
matchLabels:
app: kodexplorer
template:
metadata:
labels:
app: kodexplorer
spec:
containers:
- name: kodexplorer
image: xaljer/kodexplorer
ports:
- containerPort: 80
备注:
这里都用的yaml文件类似docker-compose的,yaml是递归定义一个不是标记语言的语言,就是类似标记和脚本,但不只是标记,可以用来做配置和数据库档案等。可以用在线的检查软件:
http://www.bejson.com/validators/yaml/;
apiVersion就是k8s APIserver的默认版本,
kind是指创建的资源类型,可以是Deployment、Job、Ingress、Service等,
metadata:包含Pod的一些元数据meta信息,比如名称、namespace、标签等信息。
spec:包括一些container,storage,volume以及其他Kubernetes需要的参数,以及诸如是否在容器失败时重新启动容器的属性。可在特定Kubernetes API找到完整的Kubernetes Pod的属性。
app 后面指定服务名
containerPort指定容器的端口
部署pod,没有设置的话默认部署在defaut-namespace 命名空间
kubectl apply -f kodexplorer-deployment.yaml
查看是否created
[root@master docker-kodexplorer]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
kodexplorer-deployment 1/1 1 1 3h38m
查看部署的pod
[root@master docker-kodexplorer]# kubectl get pods
NAME READY STATUS RESTARTS AGE
kodexplorer-deployment-8bdf4f766-rr6rq 1/1 Running 0 3h39m
部署 service
创建service服务模版文件 kodexplorer-service.yml
[root@master docker-kodexplorer]# cat kodexplorer-service.yml
apiVersion: v1
kind: Service
metadata:
name: kodexplorer-service
labels:
app: kodexplorer
spec:
ports:
- port: 80
targetPort: 80
selector:
app: kodexplorer
type: NodePort
备注:
这里就是service资源。
端口除了容器端口,还有port(Pod的端口),targetPort(service上的端口),nodePort (node上的端口,如果不设置则由kubernets自动分配)
这里没设置NodePort所以 ,服务节点对外的端口是随机生成的,运行服务
kubectl create -f kodexplorer-service.yml
查看生成的服务:
[root@master docker-kodexplorer]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kodexplorer-service NodePort 10.102.12.171 80:32086/TCP 3h37m
这里可以看到对外提供的服务端口为32086 ,登录网页测试
小结
通过部署了解了kubernets基础概念和大致架构,后续还需不断使用部署使用来加深理解和详细学习。 可以从一些关系不大复杂的分布式组件开始,比如redis、consul、etcd和rabbitMQ、elasticsearch之类。
接下将部署spark集群