kubernetes 是 google 公司基于 docker 所做的一个分布式集群,有以下主件组成
etcd : 高可用存储共享配置和服务发现,作为与 minion 机器上的 flannel 配套使用,作用是使每台 minion 上运行的 docker 拥有不同的 ip 段,最终目的是使不同 minion 上正在运行的 docker containner 都有一个与别的任意一个 containner (别的 minion 上运行的 docker containner )不一样的 IP 地址。
flannel : 网络结构支持
kube-apiserver: 不论通过 kubectl 还是使用 remote api 直接控制,都要经过 apiserver
kube-controller-manager : 对 replication controller, endpoints controller, namespace controller, andserviceaccounts controller 的循环控制,与 kube-apiserver 交互,保证这些 controller 工作
kube-scheduler : Kubernetesscheduler 的作用就是根据特定的调度算法将 pod 调度到指定的工作节点( minion )上,这一过程也叫绑定( bind)
kubelet : Kubelet 运行在 Kubernetes Minion Node 上 . 它是 container agent 的逻辑继任者
kube-proxy : kube-proxy 是 kubernetes 里运行在 minion 节点上的一个组件 , 它起的作用是一个服务代理的角色
图为 GIT+Jenkins+Kubernetes+Docker+Etcd+confd+Nginx+Glusterfs 架构 :
centos7 系统机器两台:
升级后的版本为:
[root@node6717 pods]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@node6717 pods]# uname -a
Linux node6717 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 2216:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
192.168.67.17: 用来安装 kubernetesmaster
192.168.99.160: 用作 kubernetes minion ( minion1 )
安装docker
1 。如果系统开启了防火墙则按如下步骤关闭防火墙(所有机器)
#setenforce 0
[root@master ~]# sed -i ' s/^SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
1. 安装并配置 Kubernetes master(yum 方式 )
配置 etcd
确保列出的这些项都配置正确并且没有被注释掉,下面的配置都是如此
#vim /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.67.17:2379"
systemctl enable etcd
systemctl start etcd
ss -antl 检查 2379 是否成功
[root@k8s-master ~]# lsof -i:2379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
etcd 22060 etcd 6u IPv6640833 0t0 TCP *:2379 (LISTEN)
etcd 22060 etcd 10u IPv4640839 0t0 TCP localhost:49662->localhost:2379(ESTABLISHED)
etcd 22060 etcd 12u IPv6640840 0t0 TCP localhost:2379->localhost:49662(ESTABLISHED)
KUBE_API_ADDRESS="--address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBELET_PORT="--kubelet_port=10250"
KUBE_ETCD_SERVERS="--etcd_servers=http://192.168.67.17:2379"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16--service-node-port-range=1-65535"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"
# 将SecurityContextDeny,ServiceAccount参数删除
KUBE_API_ARGS=""
###
# The following values are used to configure thekubernetes controller-manager
# defaults from config and apiserver should be adequate
# Add your own!
KUBE_CONTROLLER_MANAGER_ARGS="--node-monitor-grace-period=10s--pod-eviction-timeout=10s"
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.67.17:8080"
===============================================
[root@node6717 kubernetes]# etcdctl -C"http://192.168.67.17:2379" set /atomic.io/network/config'{"Network":"10.1.0.0/16"}'
{"Network":"10.1.0.0/16"}
mkdir -p /server/shell_scripts/k8s
vim master_daemon_start.sh
#!/bin/bash
for SERVICES in etcd kube-apiserverkube-controller-manager kube-scheduler flanneld docker
do
systemctl restart $SERVICES
systemctl status $SERVICES
done
chmod 755 master_daemon_start.sh
或
[root@Control k8s] # cat master_start.sh
systemctl enablekube-apiserver kube-scheduler kube-controller-manager etcd flanneld dockersystemctl start kube-apiserver kube-scheduler kube-controller-manageretcd flanneld docker ss -antl 检查 8080 是否成功
4. 至此 master 配置完成,运行 kubectl get nodes 可以查看有多少 minion 在运行,以及其状态。这里我们的 minion 还都没有开始安装配置,所以运行之后结果为空
# kubectl get nodes
NAME LABELS STATUS
# yum -y install flannel kubernetes docker-io
systemctl enableflanneld docker kube-proxy kubelet
#vim /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.67.17:8080"
KUBE_ETCD_SERVERS="--etcd_servers=http://192.168.67.17:2379"
配置 kubernetes , (请使用每台 minion 自己的 IP 地址比如 192.168.99.160 :代替下面的 $LOCALIP )
#vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_PORT="--port=10250"
# change the hostname to this host ’sIP address
KUBELET_HOSTNAME="--hostname_override=$LOCALIP"
KUBELET_API_SERVER="--api_servers=http://192.168.67.17:8080"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""
2. 准备启动服务 (如果本来机器上已经运行过 docker 的请看过来,没有运行过的请忽略此步骤)
运行 ifconfig ,查看机器的网络配置情况(有 docker0 )
# ifconfig docker0
Link encap:Ethernet HWaddr 02:42:B2:75:2E:67 inet addr:172.17.0.1Bcast:0.0.0.0 Mask:255.255.0.0 UP
BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0dropped:0 overruns:0 frame:0 TX packets:0
errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
warning: 在运行过 docker 的机器上可以看到有 docker0 ,这里在启动服务之前需要删掉 docker0 配置,在命令行运行 :sudo ip link delete docker0
#vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.67.17:2379"
PS :其中 atomic.io 与上面 etcd 中的 Network 对应
FLANNEL_ETCD_PREFIX="/atomic.io/network"
systemctl enable flanneld
systemctl restart flanneld
systemctl enable docker
systemctl start docker
确定两台 minion(192.168.99.160) 和一台 master ( 192.168.67.17 )都已经成功的安装配置并且服务都已经启动了。
切换到 master 机器上,运行命令 kubectl get nodes
# kubectl get nodes
NAME STATUS AGE
192.168.99.160 Ready 1m
在每个node节点,你应当注意到你有两块新的网卡docker0 和 flannel0。你应该得到不同的ip地址范围在flannel0上,就像下面这样:
inet 10.1.33.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 02:42:d1:50:5b:f2 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions0
enp2s0:flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.99.160 netmask 255.255.128.0 broadcast 192.168.127.255
inet6 fe80::3915:263a:cea4:fe8e prefixlen 64 scopeid0x20<link>
ether 4c:cc:6a:89:34:32 txqueuelen 1000 (Ethernet)
RX packets 15683491 bytes 2396283424 (2.2 GiB)
RX errors 0 dropped 1 overruns 0 frame 0
TX packets 588362 bytes 61413948 (58.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions0
inet 10.1.33.0 netmask 255.255.0.0 destination 10.1.33.0
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen500 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions0
至此,kubernetes集群已经配置并运行了,我们可以继续下面的步骤。
设置service的nodeport以后外部无法访问对应的端口的问题 每台master和minion都需要安装:
FAQ:
设置 service 的 nodeport 以后外部无法访问对应的端口的问题
关于 Service 设置为 NodePort 模式后导致外部无法访问对应的端口问题,查看下 node 节点上已经出现了 30002 端口的监听,确保服务器外部安全组等限制已经放行该端口,按照网上搜到的教程配置基本没看到要配置 iptables 相关的问题。
然后查阅了不少资料才看到 docker 1.13 版本对 iptables 的规则进行了改动,默认 FORWARD 链的规则为 DROP ,带来的问题主要一旦 DROP 后,不同主机间就不能正常通信了( kubernetes 的网络使用 flannel 的情况)。
[root@k8s-master~] # iptables-L -n
ChainINPUT (policy ACCEPT)
target prot opt source destination
KUBE-FIREWALL all -- 0.0.0.0/0 0.0.0.0/0
ChainFORWARD (policy DROP)
target protopt source destination
DOCKER-ISOLATION all -- 0.0.0.0/0 0.0.0.0/0
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
iptables 被 kubernetes 接管后的规则比较多,仔细看下 FORWARD 规则就发现了, policy DROP 状态,这就导致了我们直接访问 node 节点的 IP 加上端口会无法访问容器,问题出在 iptables 上就好解决了。
临时解决方案 ,直接设置 FORWARD 全局为 ACCEPT :
[root@k8s-master~] # iptables-P FORWARD ACCEPT
[root@k8s-master~] # iptables-L -n
ChainINPUT (policy ACCEPT)
target prot opt source destination
KUBE-FIREWALL all -- 0.0.0.0 / 0 0.0.0.0 / 0
ChainFORWARD (policy ACCEPT)
这样需要在每台 node 上执行命令,并且重启 node 后规则失效;
永久解决方案 ,修改 Docker 启动参数,在 [Service] 区域末尾加上参数:
[root@k8s-master~] # vim/usr/lib/systemd/system/docker.service
[Service]
............
ExecStartPost= /sbin/iptables -I FORWARD -s 0 . 0 . 0 . 0 / 0 -j ACCEPT
[root@k8s-master~] #systemctl daemon-reload
[root@k8s-master~] #systemctl restart docker
由于修改了 systemctl 文件,所以需要重新载入,重启 docker 就可以看到 iptables 规则已经加上 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
[root@k8s-master~] # iptables -L -n
ChainINPUT (policy DROP)
target prot opt source destination
KUBE-FIREWALL all -- 0.0.0.0/0 0.0.0.0/0
ChainFORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
为了创建一个pod,我们需要在kubernetes master上面定义一个yaml 或者 json配置文件。然后使用kubectl命令创建pod
[root@slave1 ~]# mkdir -p/k8s/pods
[root@slave1 ~]# cd/k8s/pods/
[root@slave1 ~]# catnginx.yaml
在nginx.yaml内容如下:
[root@node6717 pods]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: n