kubernetes(k8s) 使用工具部署-kubespray

前言

目前来看kubespray没那么成熟(2019/03/19)。
调研过很多部署工具,第三方得,官方得都试过。最终还是选择了kubespray,只因为它是官方工具,以及使用成熟得ansible方式。ansible是一个好工具。基于kubeadm,将kubernetes组件部署到容器上。
已测试4节点部署,一个master,三个node
kubernets版本:v1.13.4
本文章基于master分支: 3c4cbf133e76723fc0f360d15433795b08101e67

commit 3c4cbf133e76723fc0f360d15433795b08101e67
Author: Manuel Cintron <[email protected]>
Date:   Wed Mar 13 15:58:25 2019 -0500

    Adding ability to override dashboard replica count (#4344)

分享另外一个工具rancher,简单到令人发指:
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/#2-install-rancher

环境准备

整体介绍

使用vmware虚拟机作为测试环境。每台虚拟机添加3张网卡,2张nat,一张host-only,实际上没用到多余得2张网卡,这里只是冗余配置。
全程使用root权限。
镜像使用CentOS-7-x86_64-Minimal-1708.iso。
虚拟机配置及功能介绍:

  • master
    控制节点。部署节点。
    1核,2G内存,50G存储
    网卡一:nat模式,10.10.10.210
  • node01
    计算,数据库(etcd)。
    1核,2G内存,50G存储
    网卡一:nat模式,10.10.10.211
  • node02
    计算,数据库(etcd)。
    1核,2G内存,50G存储
    网卡一:nat模式,10.10.10.212
  • node03
    计算,数据库(etcd)。
    1核,2G内存,50G存储
    网卡一:nat模式,10.10.10.213

基础环境配置

1. 加速源配置(每台机器均执行)
yum源
yum install -y wget
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
pip源
mkdir ~/.pip
cat > ~/.pip/pip.conf << EOF 
[global]
trusted-host=mirrors.aliyun.com
index-url=https://mirrors.aliyun.com/pypi/simple/
EOF
docker源
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://jzngeu7d.mirror.aliyuncs.com"]
}
EOF
2. 防火墙配置(每台机器均执行)
关闭firewalld
systemctl disable firewalld
systemctl stop firewalld
开启iptables
yum install iptables -y
yum install iptables-services -y
systemctl start iptables.service
systemctl enable iptables.service

iptables -F
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
service iptables save
systemctl restart iptables.service
3. 配置ip转发(每台机器均执行)
modprobe br_netfilter
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
sysctl -w net.ipv4.ip_forward=1
4. 安装docker(每台机器均执行)
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce-18.09.3 -y
systemctl enable docker
systemctl restart docker
5. 准备部署节点环境(只在master执行)
安装基础软件
yum install -y epel-release ansible git gcc openssl-devel
yum install -y python36 python36-devel python36-pip
配置免密登陆

配置主机解析:
vi /etc/hosts添加如下内容

10.10.10.210 master
10.10.10.211 node01
10.10.10.212 node02
10.10.10.213 node03

生成ssh公私钥

ssh-keygen

拷贝公钥到目的机器,注意输入密码

ssh-copy-id -i /root/.ssh/id_rsa.pub root@master
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node01
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node02
ssh-copy-id -i /root/.ssh/id_rsa.pub root@node03
准备kubespray

下载:

git clone https://github.com/kubernetes-incubator/kubespray.git /etc/kubespray

安装依赖:

pip3.6 install -r /etc/kubespray/requirements.txt
pip3.6 install -r /etc/kubespray/contrib/inventory_builder/test-requirements.txt
pip3.6 install ruamel.yaml

生成配置文件:

cp -r /etc/kubespray/inventory/sample /opt/node
declare -a IPS=(10.10.10.210 10.10.10.211 10.10.10.212 10.10.10.213)
CONFIG_FILE=/opt/node/hosts.ini 
python36 /etc/kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}

替换被墙得源:

find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i "s/gcr\.io\/google_containers/gcr\.mirrors\.ustc\.edu\.cn\/google-containers/g" {}
find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i "s/gcr\.io\/google-containers/gcr\.mirrors\.ustc\.edu\.cn\/google-containers/g" {}
find /etc/kubespray -name '*.yml' | xargs -n1 -I{} sed -i 's/quay\.io/quay-mirror\.qiniu\.com/' {}

开始部署

编辑集群配置文件

vi /opt/node/hosts.ini

[kube-master]
master

[etcd]
node01
node02
node03

[kube-node]
node01
node02
node03

[k8s-cluster:children]
kube-master
kube-node

换源:vi /opt/node/group_vars/k8s-cluster/k8s-cluster.yml

kube_image_repo: "gcr.azk8s.cn/google-containers"

开启ingress:vim /opt/node/group_vars/k8s-cluster/addons.yml

ingress_nginx_enabled: true

部署(在master节点上执行)

ansible-playbook -i /opt/node/hosts.ini --become --become-user=root /etc/kubespray/cluster.yml

当 [file download], storage.googleapis.com 无法访问而失败时。多执行几次,这个网址是可以访问得,只是速度很慢,导致ansible部署超时。还未找到合适得替换源。
部署完成后,查看集群:

kubectl get nodes
image.png

至此部署结束。

使用

1. etcd状态查询

在部署了etcd得节点执行:

export ETCDCTL_API=3
etcdctl member list \
--endpoints=10.10.10.211:2379,10.10.10.212:2379,10.10.10.213:2379 \
--cacert /etc/pki/tls/certs/ca-bundle.crt  \
--cert /etc/ssl/etcd/ssl/ca.pem \
--key /etc/ssl/etcd/ssl/ca-key.pem
kubernetes(k8s) 使用工具部署-kubespray_第1张图片
image.png

2. kubernetes简单使用。

结构简单介绍

宏观介绍两层结构:构建服务 -- 发布服务

构建服务

k8s将一组互相关联得容器放在一个pod上,由pod暴露端口提供基础服务。
k8s提供deployment概念用于构建pod。

发布服务

发布服务就是让别人访问我们得pod。这里得“别人”可以是集群内部,也可以是集群外得网络。
k8s提供service概念用于发布服务。
service主要包含4种:

  1. ClusterIP:默认方式,只有集群节点内可以访问。
  2. NodePort:外部可以通过节点真实ip访问。
  3. LoadBalancer:通过负载提供一个外部访问点。需要和云平台集成。
  4. ExternalName:外部可以通过域名访问。比如 foo.bar.example.com。这里不介绍这种
启动一个简单但齐全得应用(master节点执行)
  1. 构建基础服务 -- deployment
    这里演示两个容器组成的一个3副本pod。由于通过pod暴露端口,因此同一个pod内的容器不能使用相同的端口。
    创建deployment yml文件: vim k1_deployment.yaml
    添加如下内容:
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-rabbitmq-deployment # deployment 名称
spec:
  replicas: 3 # pod 副本数
  template:
    metadata:
      labels: # 标签,service在与pod关联时使用此值
        app: nginx-rabbitmq # 标签键值对
    spec:
      containers:
      - name: nginx # 容器名称
        image: nginx:1.7.9 # 容器镜像
        ports: # 容器端口,在这里也说成pod端口
        - containerPort: 80
      - name: rabbitmq
        image: rabbitmq:3-management
        ports:
        - containerPort: 5671
        - containerPort: 5672
        - containerPort: 15671
        - containerPort: 15672
        env: # 容器环境变量
        - name: RABBITMQ_DEFAULT_USER
          value: user
        - name: RABBITMQ_DEFAULT_PASS
          value: password

创建 deployment:kubectl create -f k1_deployment.yaml
查看deployment:kubectl get deployments

image.png

查看deployment创建的pods:kubectl get pods

image.png

此时需要拉取镜像,会耗费一定时间创建。

  1. 发布服务 -- service
    这里使用NodePort类型。
    创建service文件:vim k1_node_service.yml
    添加如下内容:
kind: Service
apiVersion: v1
metadata:
  name: nginx-rabbitmq-service-node
spec:
  type: NodePort # service 类型,默认为ClusterIP
  selector: # 与deployment对应的标签选择器
    app: nginx-rabbitmq # 标签键值对
  ports:
      - name: nginx # 若存在多个端口时,要添加名称
        protocol: TCP # 协议类型
        targetPort: 80 # pod端口(容器端口)
        port: 20000 # 集群内部映射端口,不填会随机。ClusterIP使用的端口。
        nodePort: 30000 # 集群节点映射端口,默认范围30000-32767。NodePort使用的端口。
      - name: rabbitmq5671
        protocol: TCP
        targetPort: 5671
        port: 20001
        nodePort: 30001
      - name: rabbitmq5672
        protocol: TCP
        targetPort: 5672
        port: 20002
        nodePort: 30002
      - name: rabbitmq15671
        protocol: TCP
        targetPort: 15671
        port: 20003
        nodePort: 30003
      - name: rabbitmq15672
        protocol: TCP
        targetPort: 15672
        port: 20004
        nodePort: 30004

创建service:kubectl create -f k1_node_service.yml
查看service:kubectl get service

image.png

使用chrome测试访问:
浏览器地址填写任意集群节点的ip地址,我这里使用10.10.10.210。30000是nginx,30004是rabbitmq管理端口。
kubernetes(k8s) 使用工具部署-kubespray_第2张图片
image.png

kubernetes(k8s) 使用工具部署-kubespray_第3张图片
image.png

有兴趣的也可以通过ClusterIP地址访问,此类型地址只能在集群内部可以访问到。
比如: curl 10.233.53.35:20000
kubernetes(k8s) 使用工具部署-kubespray_第4张图片
image.png

UI

chrome浏览器访问如下地址:
:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
此时我们还没有用户去登陆,需先创建用户。
在mster节点执行如下命令:

  1. 创建用户
    创建用户yml文件:vim dashboard-adminuser.yml
    添加如下内容:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

执行创建命令:kubectl create -f dashboard-adminuser.yml

  1. 绑定权限
    创建绑定文件:vim dashboard-adminuser-binding.yml
    添加如下内容:
apiVersion: rbac.authorization.k8s.io/v1
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

执行创建命令:kubectl create -f dashboard-adminuser-binding.yml

  1. 获取登陆令牌:kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
  2. 在登陆页面选择令牌,输入获得的令牌即可登陆。

3. kubernetes扩展使用

ingress

ingress一般用于http之类的代理。ingress实际上还是和nodePort类似,使用安装了ingress-controller的节点ip进行访问,未实现vip功能。
使用前面的nginx-rabbitmq deployment进行测试ingress。

1. nginx-rabbitmq-deployment

和前面一致

2. nginx-rabbitmq-service

这里使用ClusterIP类型。
创建service文件:vim k1_cluster_service.yaml

kind: Service
apiVersion: v1
metadata:
  name: nginx-rabbitmq-service-cluster
spec:
  type: ClusterIP
  selector: # 与deployment对应的标签选择器
    app: nginx-rabbitmq # 标签键值对
  ports:
      - name: nginx # 若存在多个端口时,要添加名称
        protocol: TCP # 协议类型
        targetPort: 80 # pod端口(容器端口)
        port: 20000 # 集群内部映射端口,不填会随机
      - name: rabbitmq5671
        protocol: TCP
        targetPort: 5671
        port: 20001
      - name: rabbitmq5672
        protocol: TCP
        targetPort: 5672
        port: 20002
      - name: rabbitmq15671
        protocol: TCP
        targetPort: 15671
        port: 20003
      - name: rabbitmq15672
        protocol: TCP
        targetPort: 15672
        port: 20004

执行创建命令:kubectl create -f k1_cluster_service.yaml

3. nginx-rabbitmq-ingress

用于代理nginx 和rabbitmq管理页面
创建ingress文件:vim k1_ingress.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-rabbitmq-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/add-base-url: "true"
spec:
  rules:
  - http:
      paths:
      - path: /testNginx
        backend:
          serviceName: nginx-rabbitmq-service-cluster
          servicePort: 20000
      - path: /testRabbitMQ
        backend:
          serviceName: nginx-rabbitmq-service-cluster
          servicePort: 20004

执行创建命令:kubectl create -f k1_ingress.yml
查看ingress命令:kubectl get ingress

4. 访问ingress地址

在chrome浏览器输入安装了ingress-controller节点的ip以及对应path。
我这里的环境为:

  • 10.10.10.211/testRabbitmq
  • 10.10.10.211/testNginx
    访问效果如下:


    kubernetes(k8s) 使用工具部署-kubespray_第5张图片
    image.png

    kubernetes(k8s) 使用工具部署-kubespray_第6张图片
    image.png
loadbalancer

负载一般用于ip代理。
使用节点的ip访问服务始终不是好办法。自带的loadbalancer需要与云平台集成。
集成得方式没有环境,暂无法测试。
现尝试,keepalived+NodePort方式。

1. nginx-rabbitmq-deployment

直接使用前面得,无需重复创建。

2. nginx-rabbitmq-service-node

直接使用前面创建得NodePort类型得service。

3. 部署keepalived
  1. 安装keepalived
    我这里在master节点和node03两个节点上安装。
    两个节点上均执行:
yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel
yum install -y keepalived
  1. 配置keepalived
    将两个节点得配置文件做备份。
    两个节点上均执行:mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
    修改master节点得配置文件:vim /etc/keepalived/keepalived.conf
# global_defs中:
# smtp_server改为 127.0.0.1
# ----------
# vrrp_instance VI_1中:
# 1. interface改为与vip同一网段得网卡名称
# 2. 在virtual_ipaddress中填写想要得vip
# 3. 注意priority值为100,这是优先级,从节点得优先级要比主节点得小。
! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.10.250
    }
}

修改node03节点得配置文件:vim /etc/keepalived/keepalived.conf

# global_defs中:
# smtp_server改为 127.0.0.1
# ----------
# vrrp_instance VI_1中:
# 1. interface改为与vip同一网段得网卡名称
# 2. 在virtual_ipaddress中填写想要得vip
# 3. 注意priority值为100,这是优先级,从节点得优先级要比主节点得小。
! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.10.10.250
    }
}
  1. 启动keepalived(两个节点均执行)
    systemctl start keepalived
    systemctl enable keepalived
  2. 测试keepalived
    在master节点ip a可以看到,ens33网卡多了一个vip地址。
    使用chrome浏览器输入vip+NodePort类型得端口即可访问服务。
    kubernetes(k8s) 使用工具部署-kubespray_第7张图片
    image.png

    测试vip漂移:
    在master节点:systemctl stop keepalived
    此时到node03节点ip a可以看到,ens33网卡多了一个vip地址。
    使用chrome浏览器输入vip+NodePort类型得端口访问服务。
    kubernetes(k8s) 使用工具部署-kubespray_第8张图片
    image.png
持久化存储(volume)

存储方案很多,不再举例。
参考:https://kubernetes.io/docs/concepts/storage/volumes/
由于卷是单点使用,也就是只能某个节点使用,这会导致其它节点得pod无法创建成功,当然某些外部卷可以实现漂移,但是依然只能同时只挂载在一个节点上(听说最新得openstack cinder实现了卷共享挂载)。虽然实现了多副本功能,但是对于有状态得服务,这似乎不大有用。
个人经验,可能有误。

注意事项
1. externalIPs

此参数,类似于额外的clusterIP,外部不能访问到。不要将此字段和节点ip置为相同。

排错

通过journalctl -xe可以看到集群日志。
容器输出到控制台的日志,都会以 *-json.log 的命名方式保存在 /var/lib/docker/containers/ 目录下。

使用
kubectl create -f 为创建
kubectl apply -f 为更新

你可能感兴趣的:(kubernetes(k8s) 使用工具部署-kubespray)