1.架构
pod是k8s中最小的一个单元,可以理解为k8s的一个原子,所有的服务都会部署在pod里面
pod运行在节点上面,kubelet负责调度pod,把pod运行在Node上面。
service:service的ip除了能对pod进行定位以外,还能对多个pod进行负载均衡。
整体的架构:
主节点:
ApiServer:提供了资源操作的唯一的入口,并且提供认证授权和K8S的访问控制,暴露给外界访问的,我们可以通过kubectl或者或者自己开发的客户端通过http请求或REST Api去访问API Server
ControllerManager:负责维护集群的状态,比如说故障检测,扩缩容,滚动更新等等。
Scheduler:调度模块,通过一些调度算法决定容器运行在哪个节点,就是决定把pod调度到那个节点上。
ETCD:一个分布式的K-V store,主要储存整个K8S的状态和配置,保存了pod,service,集群的状态等等一些信息,整个K8S集群需要持久化的数据都会存到ETCD里面去
KUBE-dns:整个集群的dns,通过名字去访问
dashboard:提供了一个UI界面
从节点:
Kubelet:负责维护当前节点上容器的生命周期,负责如何去创建容器,创建网络,创建volume等等的管理工作,相当于Master的代理,engine。
Kube-proxy:如果想要暴露一些端口给外界访问,则要用到kube-proxy,负载均衡服务发现等等,也是通过kube-proxy来实现的。相对于为servcie这个概念提供了落地的方法。
整个流程:
kubectl向集群发起一个命令,请求经过认证过后,经过Scheduler的各种的策略计算去得到一个目标的node,然后告诉APIServer,
APIServer就请求了相关Node的Kubelet,然后通过Kubelet把这个pod运行起来,APIServer还会将这个pod的信息存储到ETCD,pod运行起来之后,ControllerManager就会管理pod的状态。
2.K8S的设计理念
pod的内部通信:
同一个node,不同的pod:
不同node 不同pod:
3. 安装K8S集群之前的准备:
这一次我们并不是安装的是单节点的k8s集群,而是有主从配置的多节点的集群:
1.首先需要服务器的配置如下:我当然是用centos的系统:
首先就是要准备好这三台装有docker环境的linux服务器关闭selinux。ok,准备好了,hostname也配置好了。
2.接受所有ip的数据包转发:
vi /lib/systemd/system/docker.service
#找到ExecStart=xxx,在这行上面加入一行,内容如下:(k8s的网络需要)
ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT
重启服务:
$ systemctl daemon-reload
$ service docker restart
3.然后进行系统的设置:
1.关闭、禁用防火墙(让所有机器之间都可以通过任意端口建立连接)
2.设置系统参数 - 允许路由转发,不对bridge的数据进行处理
#写入配置文件
$ cat <<EOF > /etc/sysctl.d/k8s.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/k8s.conf
4.kubernetes的安装有几种方式,不管是kube-admin还是社区贡献的部署方案都离不开这几种方式:
- 使用现成的二进制文件 https://github.com/kubernetes/kubernetes/
直接从官方或其他第三方下载,就是kubernetes各个组件的可执行文件。拿来就可以直接运行了。不管是centos,ubuntu还是其他的linux发行版本,只要gcc编译环境没有太大的区别就可以直接运行的。使用较新的系统一般不会有什么跨平台的问题。
- 使用源码编译安装
编译结果也是各个组件的二进制文件,所以如果能直接下载到需要的二进制文件基本没有什么编译的必要性了。
- 使用镜像的方式运行
同样一个功能使用二进制文件提供的服务,也可以选择使用镜像的方式。就像nginx,像mysql,我们可以使用安装版,搞一个可执行文件运行起来,也可以使用它们的镜像运行起来,提供同样的服务。kubernetes也是一样的道理,二进制文件提供的服务镜像也一样可以提供。
这里呢使用二进制包来安装,这也是目前企业生产环境中广为使用的方式,但对K8S管理人员的要求较高。
ok 把二进制得文件下载下来之后,分发到各台机器上去。名字改为了bin,因为home得bin默认得加入到了环境变量里面去了
5.配置配置文件
1.先下载配置文件
#到home目录下载项目
$ cd
$ git clone https://github.com/liuyi01/kubernetes-starter.git
#看看git内容
$ cd ~/kubernetes-starter && ls
相关配置文件解释
- gen-config.sh
shell脚本,用来根据每个同学自己的集群环境(ip,hostname等),根据下面的模板,生成适合大家各自环境的配置文件。生成的文件会放到target文件夹下。
- kubernetes-simple
简易版kubernetes配置模板(剥离了认证授权)。 适合刚接触kubernetes的同学,首先会让大家在和kubernetes初次见面不会印象太差(太复杂啦~~),再有就是让大家更容易抓住kubernetes的核心部分,把注意力集中到核心组件及组件的联系,从整体上把握kubernetes的运行机制。
- kubernetes-with-ca
在simple基础上增加认证授权部分。大家可以自行对比生成的配置文件,看看跟simple版的差异,更容易理解认证授权的(认证授权也是kubernetes学习曲线较高的重要原因)
- service-config
这个先不用关注,它是我们曾经开发的那些微服务配置。 等我们熟悉了kubernetes后,实践用的,通过这些配置,把我们的微服务都运行到kubernetes集群中。
2.下载下来配置文件后需要去配置相关得配置
#cd到之前下载的git代码目录
$ cd ~/kubernetes-starter
#编辑属性配置(根据文件注释中的说明填写好每个key-value)
$ vi config.properties
#kubernetes二进制文件目录,eg: /home/michael/bin 注意这个路径要正确
BIN_PATH=/home/root/bin
#当前节点ip, eg: 192.168.1.102
NODE_IP=192.168.237.133
#etcd服务集群列表, eg: http://192.168.1.102:2379
#如果已有etcd集群可以填写现有的。没有的话填写:http://${MASTER_IP}:2379 (MASTER_IP自行替换成自己的主节点ip)
##如果用了证书,就要填写https://${MASTER_IP}:2379 (MASTER_IP自行替换成自己的主节点ip)
ETCD_ENDPOINTS=http://192.168.237.134:2379
#kubernetes主节点ip地址, eg: 192.168.1.102
MASTER_IP=192.168.237.134
3.#生成配置文件,确保执行过程没有异常信息
$ ./gen-config.sh simple 这里要自己手动确保每个配置文件的变量都被替换成功了,MD这里把我坑惨了
gen-config.sh文件得内容:
#!/bin/bash
declare -A kvs=()
function replace_files() {
local file=$1
if [ -f $file ];then
echo "$file"
for key in ${!kvs[@]}
do
value=${kvs[$key]}
value=${value//\//\\\/}
sed -i "s/{{$key}}/${value}/g" $file
done
return 0
fi
if [ -d $file ];then
for f in `ls $file`
do
replace_files "${file}/${f}"
done
fi
return 0
}
target=$1
if [ "$target" != "simple" -a "$target" != "with-ca" ];then
echo -e "Usage:\n\t sh gen-config.sh (simple / with-ca)"
exit 1
fi
if [ "$target" == "simple" ];then
folder="kubernetes-simple"
else
folder="kubernetes-with-ca"
fi
target="target"
rm -fr $target
cp -r $folder $target
cd $target
echo "====替换变量列表===="
while read line;do
if [ "${line:0:1}" == "#" -o "${line:0:1}" == "" ];then
continue;
fi
key=${line/=*/}
value=${line#*=}
echo "$key=$value"
kvs["$key"]="$value"
done < ../config.properties
echo "===================="
echo "====替换配置文件===="
for element in `ls`
do
dir_or_file=$element
if [ ! -d $dir_or_file ];then
continue
fi
replace_files $dir_or_file
done
echo "================="
echo "配置生成成功,位置: `pwd`"
注意一定不要使用sh去运行这个文件 一定要用./的这种方式
#查看生成的配置文件,确保脚本执行成功
$ find target/ -type f
好了,剩下两台机器也按照如上的方式生成就好。
执行gen-config.sh常见问题:
gen-config.sh: 3: gen-config.sh: Syntax error: "(" unexpected
bash版本过低,运行:bash -version查看版本,如果小于4需要升级
不要使用 sh gen-config.sh的方式运行(sh和bash可能不一样哦)
config.properties文件填写错误,需要重新生成 再执行一次./gen-config.sh simple即可,不需要手动删除target
4.基础集群部署
1. 部署ETCD(主节点)
简介
kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运行的pod,deployment,service等等。都需要持久化。etcd就是它的数据中心。生产环境中为了保证数据中心的高可用和数据的一致性,一般会部署最少三个节点。我们这里以学习为主就只在主节点部署一个实例。
如果你的环境已经有了etcd服务(不管是单点还是集群),可以忽略这一步。前提是你在生成配置的时候填写了自己的etcd endpoint哦~
1.2 部署
etcd的二进制文件和服务的配置我们都已经准备好,现在的目的就是把它做成系统服务并启动。,因为这个是在主节点上搭建ETCD,所以需要在主节点node7上操作
首先就是要把服务的配置copy到系统服务目录
cp ~/kubernetes-starter/target/master-node/etcd.service /lib/systemd/system/
然后enable服务
systemctl enable etcd.service
然后创建工作目录(保存数据的地方)
mkdir -p /var/lib/etcd
启动服务
service etcd start
journalctl -xe查看:
找了半天发现是指向etcd可执行文件的路径不正确,修改过后,能启动服务了
然后查看启动日志确保没有异常
journalctl -f -u etcd.service
然后看看2379的端口是不是正常的监听:
netstat -lntp
最后看看etcd的配置,这个配置是我们通过脚本文件来生成的。
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/root/bin/etcd \
--name=192.168.237.134 \
--listen-client-urls=http://192.168.237.134:2379,http://127.0.0.1:2379 \
--advertise-client-urls=http://192.168.237.134:2379 \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
2. 部署APIServer(主节点)
2.1 简介
kube-apiserver是Kubernetes最重要的核心组件之一,主要提供以下的功能
- 提供集群管理的REST API接口,包括认证授权(我们现在没有用到)数据校验以及集群状态变更等
- 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd)
生产环境为了保证apiserver的高可用一般会部署2+个节点,在上层做一个lb做负载均衡,比如haproxy。由于单节点和多节点在apiserver这一层说来没什么区别,所以我们学习部署一个节点就足够啦
2.2 部署
首先还是呵部署etcd一样,把服务的配置copy到系统服务目录
cp target/master-node/kube-apiserver.service /lib/systemd/system/
其次, 然后enable服务
systemctl enable kube-apiserver.service
启动服务
service kube-apiserver start
查看服务启动的日志,确保没有异常:
journalctl -f -u kube-apiserver
看端口:
api-server的配置:
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/root/bin/kube-apiserver \
--admission-control=NamespaceLifecycle,LimitRanger,DefaultStorageClass,ResourceQuota,NodeRestriction \
--insecure-bind-address=0.0.0.0 \
--kubelet-https=false \
--service-cluster-ip-range=10.68.0.0/16 \
--service-node-port-range=20000-40000 \
--etcd-servers=http://192.168.237.134:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/lib/audit.log \
--event-ttl=1h \
--v=2
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
重点配置说明:
[Unit]
Description=Kubernetes API Server
...
[Service]
#可执行文件的位置
ExecStart=/home/michael/bin/kube-apiserver \
#非安全端口(8080)绑定的监听地址 这里表示监听所有地址
--insecure-bind-address=0.0.0.0 \
#不使用https
--kubelet-https=false \
#kubernetes集群的虚拟ip的地址范围
--service-cluster-ip-range=10.68.0.0/16 \
#service的nodeport的端口范围限制
--service-node-port-range=20000-40000 \
#很多地方都需要和etcd打交道,也是唯一可以直接操作etcd的模块
--etcd-servers=http://192.168.1.102:2379 \
3.部署ControllerManager(主节点)
3.1 简介
Controller Manager由kube-controller-manager和cloud-controller-manager组成,是Kubernetes的大脑,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态。 kube-controller-manager由一系列的控制器组成,像Replication Controller控制副本,Node Controller节点控制,Deployment Controller管理deployment等等 cloud-controller-manager在Kubernetes启用Cloud Provider的时候才需要,用来配合云服务提供商的控制
controller-manager、scheduler和apiserver 三者的功能紧密相关,一般运行在同一个机器上,我们可以把它们当做一个整体来看,所以保证了apiserver的高可用即是保证了三个模块的高可用。也可以同时启动多个controller-manager进程,但只有一个会被选举为leader提供服务。
3.2 部署
$ cp target/master-node/kube-controller-manager.service /lib/systemd/system/
$ systemctl enable kube-controller-manager.service
$ service kube-controller-manager start
$ journalctl -f -u kube-controller-manager
配置文件:
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/root/bin/kube-controller-manager \
--address=127.0.0.1 \
--master=http://127.0.0.1:8080 \
--allocate-node-cidrs=true \
--service-cluster-ip-range=10.68.0.0/16 \
--cluster-cidr=172.20.0.0/16 \
--cluster-name=kubernetes \
--leader-elect=true \
--cluster-signing-cert-file= \
--cluster-signing-key-file= \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
重点配置说明:
[Unit]
Description=Kubernetes Controller Manager
...
[Service]
ExecStart=/home/michael/bin/kube-controller-manager \
#对外服务的监听地址,这里表示只有本机的程序可以访问它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080 \
#服务虚拟ip范围,同apiserver的配置
--service-cluster-ip-range=10.68.0.0/16 \
#pod的ip地址范围
--cluster-cidr=172.20.0.0/16 \
#下面两个表示不使用证书,用空值覆盖默认值
--cluster-signing-cert-file= \
--cluster-signing-key-file= \
...
4.部署Scheduler(主节点)
4.1 简介
kube-scheduler负责分配调度Pod到集群内的节点上,它监听kube-apiserver,查询还未分配Node的Pod,然后根据调度策略为这些Pod分配节点。我们前面讲到的kubernetes的各种调度策略就是它实现的。
4.2 部署
通过系统服务方式部署
$ cp target/master-node/kube-scheduler.service /lib/systemd/system/
$ systemctl enable kube-scheduler.service
$ service kube-scheduler start
$ journalctl -f -u kube-scheduler
配置:
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/root/bin/kube-scheduler \
--address=127.0.0.1 \
--master=http://127.0.0.1:8080 \
--leader-elect=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
重点配置说明:
[Unit]
Description=Kubernetes Scheduler
...
[Service]
ExecStart=/home/michael/bin/kube-scheduler \
#对外服务的监听地址,这里表示只有本机的程序可以访问它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080 \
...