一, kubernetes搭建云消息服务
使用kubernetes+docker+kafka搭建云消息服务。
1.1 创建docker本地仓库
(此步骤是为了创建一个docker本地仓库,这个仓库可以存储后面步骤制作好的zookeeper镜像及kafka镜像,方便其他host节点从此本地仓库下载自制的镜像。)
1. centos7上安装docker。
以root用户运行 yum install docker。
2. 把docker加入到自动启动列表中。
systemctl enable docker
systemctl start docker
systemctl status docker (显示状态为running说明服务配置成功。)
3. 搭建docker私有仓库
3.1 下载registry镜像 docker pull registry
3.2 查看镜像是否下载成功 docker images
3.3 启动registry镜像的一个容器:
docker run -d -p 5000:5000 --privileged=true -v /opt/data/registry/:/var/lib/registry registry
命令说明:
docker run registry 启动镜像registry的一个容器。
-d 以后台运行容器。
-p <主机端口:容器端口> 把主机端口映射到容器端口,参考:http://blog.csdn.net/qq_29994609/article/details/51730640
-v <本地目录:容器目录> 把本地目录挂在到容器目录,这样容器中存储在这个目录中的数据会被持久化到主机硬盘中。
use '--privileged=true' to persistently storing data to local storage. 参考:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4247577 (docker容器赋予本地路径权限的三种方式。)
3.4 查看容器是否启动成功 docker ps。
两个docker常用的命令:
docker exec -it f77f2cd38d70 sh //在docker容器中执行一个命令。
docker stop f77f2cd38d70 //停止一个docker容器。
3.5 本地仓库创建完成就可以向本地仓库添加镜像了,本实践首先从docker.io下载一个nginx镜像,然后把这个nginx镜像存储到本地docker镜像仓库。
(在实际使用中一般是创建自己的镜像,然后存储到本地仓库中供下载。)
3.5.1 创建一个镜像(此处直接从docker.io拉取一个镜像当作自己创作的镜像) docker pull nginx。
3.5.2 查看是否下载成功 docker ps。
3.5.3 修改镜像的tag docker tag nginx 192.168.1.100:5000/nginx
3.5.4 上传镜像到本地仓库 docker push 192.168.1.100:5000/nginx
3.6 验证本地仓库可用。
3.6.1 删除本地镜像 docker rmi 192.168.1.100:5000/nginx
3.6.2 重新从本地仓库下载镜像 docker pull 192.168.1.100:5000/nginx
3.6.3 查看本地镜像 docker images 有下载下来的nginx镜像,本地仓库配置成功。
(上传成功的镜像存储在docker容器中的/var/lib/registry目录下,因为在运行命令的时候此目录映射到本机目录/opt/data/registry/,所以实际上镜像都存储在物理机的/opt/data/registry/目录下,所以能够持久化。)
创建本地仓库遇到的一个问题:
- 镜像上传到本地docker镜像仓库失败
[root@localhost Desktop]# docker push 192.168.1.100:5000/nginx
The push refers to a repository [192.168.1.100:5000/nginx]
Get https://192.168.1.100:5000/v1/_ping: http: server gave HTTP response to HTTPS client
[root@localhost Desktop]#
解决方法:
修改配置文件: /etc/sysconfig/docker,修改行 OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --insecure-registry 192.168.1.100:5000',添加 --insecure-registry 192.168.1.100:5000
重启docker systemctl restart docker
重新运行registry容器 docker run -d -p 5000:5000 --privileged=true -v /opt/data/registry/:/var/lib/registry registry
重新上传镜像 docker push 192.168.1.100:5000/nginx
结果:上传成功。
[root@localhost docker]# docker push 192.168.1.100:5000/nginx
The push refers to a repository [192.168.1.100:5000/nginx]
a103d141fc98: Pushed
73e2bd445514: Pushed
2ec5c0a4cb57: Pushed
latest: digest: sha256:926b086e1234b6ae9a11589c4cece66b267890d24d1da388c96dd8795b2ffcfb size: 948
1.2 搭建etcd集群
kubernetes中使用etcd主要用来做服务发现,此段展示了如何搭建一个etcd集群。
在搭建etcd集群之前,为了验证方便,需要关闭centos的防火墙firewalld和iptables服务。
systemctl stop firewalld
systemctl disable firewalld
- 下面步骤展示了如何搭建一个etcd集群
“`
1. 安装etcd
yum install etcd -y
(yum安装完成后配置文件所在的默认路径为 /etc/etcd/etcd.conf )
2. 安装完成之后修改各个host上的etcd配置文件。
node1:
ETCD_NAME="node1"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" #本地监听端口,用于集群内通信。
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" #客户端监听端口,用于etcd与客户端通信。
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.100:2380" #通知etcd集群其他节点本节点的集群监听端口。(此处URLS=后面写的是自己的地址)
ETCD_INITIAL_CLUSTER="node1=http://192.168.1.100:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.100:2379" #给客户端使用的监听端口。
node2:
#[Member]
#ETCD_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="node2"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.102:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.102:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
ETCD_INITIAL_CLUSTER="node1=http://192.168.1.100:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"
#ETCD_ENABLE_V2="true"
node3:
#[Member]
#ETCD_CORS=""
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
ETCD_NAME="node3"
#ETCD_SNAPSHOT_COUNT="100000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
#ETCD_QUOTA_BACKEND_BYTES="0"
#
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.103:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.103:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_DISCOVERY_SRV=""
ETCD_INITIAL_CLUSTER="node1=http://192.168.1.100:2380,node2=http://192.168.1.102:2380,node3=http://192.168.1.103:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_STRICT_RECONFIG_CHECK="true"
- 修改完成之后在各个节点上分别执行 systemctl enable etcd 和 systemctl start etcd 来启动etcd服务。
- 各个节点都启动etcd服务之后执行命令 etcdctl member list查看集群中的成员。
验证集群可用性:
case1: (首先查看集群状态,发现100上的etcd为leader。) [root@localhost etcd]# etcdctl member list 4490eae103912db6: name=node3 peerURLs=http://192.168.1.103:2380 clientURLs=http://192.168.1.103:2379 isLeader=false a3021b0bf88e3192: name=node1 peerURLs=http://192.168.1.100:2380 clientURLs=http://192.168.1.100:2379 isLeader=true ae89693f33672f5f: name=node2 peerURLs=http://192.168.1.102:2380 clientURLs=http://192.168.1.102:2379 isLeader=false (重新启动100上的etcd服务。) [root@localhost etcd]# systemctl stop etcd [root@localhost etcd]# systemctl start etcd (发现etcd集群的leader进行了切换,从100变成了102。) [root@localhost etcd]# etcdctl member list 4490eae103912db6: name=node3 peerURLs=http://192.168.1.103:2380 clientURLs=http://192.168.1.103:2379 isLeader=false a3021b0bf88e3192: name=node1 peerURLs=http://192.168.1.100:2380 clientURLs=http://192.168.1.100:2379 isLeader=false ae89693f33672f5f: name=node2 peerURLs=http://192.168.1.102:2380 clientURLs=http://192.168.1.102:2379 isLeader=true [root@localhost etcd]# case2: 在机器102上执行命令etcdctl set test/gx1 1 //实际上就是往etcd数据库中存储了一个k-v对。 在机器103上执行命令etcdctl set test/gx2 2 //存储了另外一个k-v对。 在机器100上执行命令etcdctl get test/gx1能够得到正确的值,执行etcdctl get test/gx2也能得到正确的值。
- 经过以上步骤etcd集群就安装完成了。
- 搭建etcd集群的一个好的博客连接:https://www.cnblogs.com/zhenyuyaodidiao/p/6237019.html
1.3 搭建kubernetes集群
1. 在机器100,102,103上禁用防火墙服务
systemctl stop firewalld
systemctl disable firewalld
2. 在机器100,102,103上安装kubernetes
yum install kubernetes
3. 在机器100上执行以下命令配置master。
(kubernetes集群的master需要启动以下服务:kube-apiserver, kube-controller-manager和kube-scheduler)
修改文件 /etc/kubernetes/apiserver
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
#
# The address on the local server to listen to.
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"
# Port minions listen on
# KUBELET_PORT="--kubelet-port=10250"
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.1.100:2379"
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"
# Add your own!
KUBE_API_ARGS=""
修改文件/etc/kubernetes/config。
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://192.168.1.100:8080"
启动相应服务并设置为自动启动。
[root@k8s-master ~]# systemctl enable kube-apiserver.service
[root@k8s-master ~]# systemctl start kube-apiserver.service
[root@k8s-master ~]# systemctl enable kube-controller-manager.service
[root@k8s-master ~]# systemctl start kube-controller-manager.service
[root@k8s-master ~]# systemctl enable kube-scheduler.service
[root@k8s-master ~]# systemctl start kube-scheduler.service
4. 在102和103上执行以下命令配置kubernetes集群node。
修改/etc/kubernetes/config文件。
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://192.168.1.100:8080"
修改配置文件 /etc/kubernetes/kubelet。
ddress for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"
# The port for the info server to serve on
# KUBELET_PORT="--port=10250"
# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=k8s-node-1"
# location of the api-server
KUBELET_API_SERVER="--api-servers=http://192.168.1.100:8080"
# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
# Add your own!
KUBELET_ARGS=""
在102和103上均执行以下命令,添加kubelet和kube-proxy服务到自动启动。
[root@k8s-master ~]# systemctl enable kubelet.service
[root@k8s-master ~]# systemctl start kubelet.service
[root@k8s-master ~]# systemctl enable kube-proxy.service
[root@k8s-master ~]# systemctl start kube-proxy.service
5. 到此为止kubernetes已经搭建完成了,在master上可以查看集群状态。
[root@localhost kubernetes]# kubectl -s http://192.168.1.100:8080 get nodes
NAME STATUS AGE
k8s-node-1 Ready 2m
k8s-node-2 Ready 2m
[root@localhost kubernetes]#
注意:
1. 在kubernets的配置文件中的各个属性最好不用下划线,比如属性 KUBELET_HOSTNAME="--hostname-override=k8s-node-1",如果改成k8s_node_1的话,
那么通过命令 kubectl get nodes 不能显示出这个带下划线的节点。
2. kubectl get nodes的节点信息更新需要一定的时间,不会实时更新。
- 搭建kubernetes集群的几个有用的链接:
https://www.cnblogs.com/zhenyuyaodidiao/p/6500830.html
http://dockone.io/article/618 #flannel说明与配置。
1.4 在kubernetes集群的各个节点上安装配置flannel服务
- 在三台机器上均安装flannel
yum -y install flannel
- 在etcd中创建变量
etcdctl set /teamsun/network/config '{ "Network": "10.1.0.0/16" }'
- 在三台机器上均执行 mkdir -p /var/log/k8s/flannel/ 来创建flannel的日志目录
- 配置三台机器的环境变量:/etc/sysconfig/flanneld
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://192.168.12.12:2379,http://192.168.12.13:2379,http://192.168.12.14:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/teamsun/network"
# Any additional options that you want to pass
FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/k8s/flannel/"
- 依次在三台机器上启动flanneld
systemctl stop flanneld
systemctl start flanneld
- flanneld运行完成之后会在每个设备上生成一个子网配置文件。
在12.12上查看cat /run/flannel/subnet.env
[root@localhost sysconfig]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.1.0.0/16
FLANNEL_SUBNET=10.1.39.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@localhost sysconfig]#
在12.13上查看cat /run/flannel/subnet.env
[root@localhost sysconfig]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.1.0.0/16
FLANNEL_SUBNET=10.1.85.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@localhost sysconfig]#
在12.14上查看cat /run/flannel/subnet.env
[root@localhost sysconfig]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.1.0.0/16
FLANNEL_SUBNET=10.1.84.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@localhost sysconfig]#
生成subnet.env之后flannld会有一个脚本把subnet.env转换写成一个docker的环境变量文件/run/flannel/docker
在12.12上查看cat /run/flannel/docker
[root@localhost sysconfig]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=10.1.39.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=10.1.39.1/24 --ip-masq=true --mtu=1472"
[root@localhost sysconfig]#
在12.13上查看cat /run/flannel/docker
[root@localhost sysconfig]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=10.1.85.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=10.1.39.1/24 --ip-masq=true --mtu=1472"
[root@localhost sysconfig]#
在12.14上查看cat /run/flannel/docker
[root@localhost sysconfig]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=10.1.84.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=10.1.39.1/24 --ip-masq=true --mtu=1472"
[root@localhost sysconfig]#
- 在三个设备上分别执行以下命令使得docker的环境变量生效。
source /run/flannel/docker
- 查看systemctl的docker.service配置文件/usr/lib/systemd/system/docker.service,在docker的启动参数execStart中已经包含了环境变量DOCKER_NETWORK_OPTIONS,
而在第6步骤,我们已经使得flanneld生成的环境变量生效了,所以在启动docker的时候使用的就是flanneld生成的子网段,这样就把flanneld和docker结合了起来。
- 在每个node节点上都重新启动docker服务。
- 测试
在12.13上下载busybox镜像,在12.14上下载busybox镜像,分别启动容器。
docker run -it 192.168.12.12:5000/busybox sh
进入容器后执行ifconfig,发现ip段与flannel分配的ip段相同。
两个在不同主机上的container互相ping可以ping通,验证通过。
1.1 ~ 1.4步骤执行完成之后kubernetes环境就搭建好了,后面的问题就是如何在kubernetes上搭建zookeeper服务和kafka服务来对外提供云消息服务了。