左邊__

左邊__ 查看完整档案

厦门编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

左邊__ 收藏了文章 · 2019-09-03

Kubernetes的几种主流部署方式02-kubeadm部署高可用集群

在上篇文章minikube部署中,有提到Minikube部署Kubernetes的核心就是Kubeadm,这篇文章来详细说明下Kubeadm原理及部署步骤。写这篇文章的时候,Kubernetes1.14刚刚发布,所以部署步骤以1.14版为主。

Kubeadm原理简述

Kubeadm工具的出发点很简单,就是尽可能简单的部署一个生产可用的Kubernetes集群。实际也确实很简单,只需要两条命令:

# 创建一个 Master 节点
$ kubeadm init

# 将一个 Node 节点加入到当前集群中
$ kubeadm join <Master 节点的 IP 和端口 >

kubeadm做了这些事
执行 kubeadm init时:

  • 自动化的集群机器合规检查
  • 自动化生成集群运行所需的各类证书及各类配置,并将Master节点信息保存在名为cluster-info的ConfigMap中。
  • 通过static Pod方式,运行API server, controller manager 、scheduler及etcd组件。
  • 生成Token以便其他节点加入集群

执行 kubeadm join时:

  • 节点通过token访问kube-apiserver,获取cluster-info中信息,主要是apiserver的授权信息(节点信任集群)。
  • 通过授权信息,kubelet可执行TLS bootstrapping,与apiserver真正建立互信任关系(集群信任节点)。

简单来说,kubeadm做的事就是把大部分组件都容器化,通过StaticPod方式运行,并自动化了大部分的集群配置及认证等工作,简单几步即可搭建一个可用Kubernetes的集群。

这里有个问题,为什么不把kubelet组件也容器化呢,是因为,kubelet在配置容器网络、管理容器数据卷时,都需要直接操作宿主机,而如果现在 kubelet 本身就运行在一个容器里,那么直接操作宿主机就会变得很麻烦。比如,容器内要做NFS的挂载,需要kubelet先在宿主机执行mount挂载NFS。如果kubelet运行在容器中问题来了,如果kubectl运行在容器中,要操作宿主机的Mount Namespace是非常复杂的。所以,kubeadm选择把kubelet运行直接运行在宿主机中,使用容器部署其他Kubernetes组件。所以,Kubeadm部署要安装的组件有Kubeadm、kubelet、kubectl三个。

上面说的是kubeadm部署方式的一般步骤,kubeadm部署是可以自由定制的,包括要容器化哪些组件,所用的镜像,是否用外部etcd,是否使用用户证书认证等以及集群的配置等等,都是可以灵活定制的,这也是kubeadm能够快速部署一个高可用的集群的基础。详细的说明可以参考官方Reference。但是,kubeadm最重要的作用还是解决集群部署问题,而不是集群配置管理的问题,官方也建议把Kubeadm作为一个基础工具,在其上层再去量身定制适合自己的集群的管理工具(例如minikube)。

Kubeadm部署一个高可用集群

Kubernetes的高可用

Kubernetes的高可用主要指的是控制平面的高可用,简单说,就是有多套Master节点组件和Etcd组件,工作节点通过负载均衡连接到各Master。HA有两种做法,一种是将etcd与Master节点组件混布在一起:

clipboard.png

另外一种方式是,使用独立的Etcd集群,不与Master节点混布:

clipboard.png

两种方式的相同之处在于都提供了控制平面的冗余,实现了集群高可以用,区别在于:
Etcd混布方式:

  • 所需机器资源少
  • 部署简单,利于管理
  • 容易进行横向扩展
  • 风险大,一台宿主机挂了,master和etcd就都少了一套,集群冗余度受到的影响比较大。

Etcd独立部署方式:

  • 所需机器资源多(按照Etcd集群的奇数原则,这种拓扑的集群关控制平面最少就要6台宿主机了)。
  • 部署相对复杂,要独立管理etcd集群和和master集群。
  • 解耦了控制平面和Etcd,集群风险小健壮性强,单独挂了一台master或etcd对集群的影响很小。

部署环境

由于机器资源不足,下面的部署测试,只会以混布的方式部署一个1*haproxy,2*master,2*node,共5台机器的集群,实际上由于etcd选举要过半数,至少要3台master节点才能构成高可用,在生产环境,还是要根据实际情况,尽量选择风险低的拓扑结构。

  • 机器:

master-1:192.168.41.230 (控制平面节点1)
master-2:192.168.41.231 (控制平面节点2)
node-1:172.16.201.108 (工作节点1)
node-2:172.16.201.109 (工作节点2)
haproxy:192.168.41.231 (haproxy)

  • 系统内核版本:
# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core) 
# uname -r               
5.0.5-1.el7.elrepo.x86_64
  • 集群版本

kubeadm:1.14.0
Kubernetes:1.14.0
Docker:Community 18.09.4
haproxy: 1.5.18

部署步骤

机器准备

在所有节点上操作:
  • 关闭selinux,firewall
setenforce  0
sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config 
systemctl stop firewalld
systemctl disable firewalld
  • 关闭swap,(1.8版本后的要求,目的应该是不想让swap干扰pod可使用的内存limit)
swapoff -a
  • 修改下面内核参数,否则请求数据经过iptables的路由可能有问题
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

安装kubeadm、docker

在除了haproxy以外所有节点上操作
  • 将Kubernetes安装源改为阿里云,方便国内网络环境安装
cat << EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
  • 安装docker-ce
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum install -y docker-ce
  • 安装kubelet kubeadm kubectl
 yum install -y  kubelet kubeadm kubectl

安装配置负载均衡

在haproxy节点操作:
# 安装haproxy
yum install haproxy -y 

# 修改haproxy配置
cat << EOF > /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

defaults
    mode                    tcp
    log                     global
    retries                 3
    timeout connect         10s
    timeout client          1m
    timeout server          1m

frontend kube-apiserver
    bind *:6443 # 指定前端端口
    mode tcp
    default_backend master

backend master # 指定后端机器及端口,负载方式为轮询
    balance roundrobin
    server master-1  192.168.41.230:6443 check maxconn 2000
    server master-2  192.168.41.231:6443 check maxconn 2000
EOF

# 开机默认启动haproxy,开启服务
systemctl enable haproxy
systemctl start haproxy

# 检查服务端口情况:
# netstat -lntup | grep 6443
tcp        0      0 0.0.0.0:6443            0.0.0.0:*               LISTEN      3110/haproxy

部署Kubernetes

在master-1节点操作:
  • 准备集群配置文件,目前用的api版本为v1beta1,具体配置可以参考官方reference
cat << EOF > /root/kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.14.0 # 指定1.14版本
controlPlaneEndpoint: 192.168.41.232:6443 # haproxy地址及端口
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 指定镜像源为阿里源
networking:
  podSubnet: 10.244.0.0/16 # 计划使用flannel网络插件,指定pod网段及掩码
EOF
  • 执行节点初始化
systemctl enable kubelet
systemctl start kubelet
kubeadm  config images pull  --config kubeadm-config.yaml  # 通过阿里源预先拉镜像
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs

安装成功,可以看到输出

You can now join any number of the control-plane node running the following command on each as root:
# master节点用以下命令加入集群:

  kubeadm join 192.168.41.232:6443 --token ocb5tz.pv252zn76rl4l3f6 \
    --discovery-token-ca-cert-hash sha256:141bbeb79bf58d81d551f33ace207c7b19bee1cfd7790112ce26a6a300eee5a2 \
    --experimental-control-plane --certificate-key 20366c9cdbfdc1435a6f6d616d988d027f2785e34e2df9383f784cf61bab9826

Then you can join any number of worker nodes by running the following on each as root:
# 工作节点用以下命令加入集群:
kubeadm join 192.168.41.232:6443 --token ocb5tz.pv252zn76rl4l3f6 \
    --discovery-token-ca-cert-hash sha256:141bbeb79bf58d81d551f33ace207c7b19bee1cfd7790112ce26a6a300eee5a2 

原来的kubeadm版本,join命令只用于工作节点的加入,而新版本加入了 --experimental-contaol-plane 参数后,控制平面(master)节点也可以通过kubeadm join命令加入集群了。

  • 加入另外一个master节点
在master-2操作:
kubeadm join 192.168.41.232:6443 --token ocb5tz.pv252zn76rl4l3f6 \
--discovery-token-ca-cert-hash sha256:141bbeb79bf58d81d551f33ace207c7b19bee1cfd7790112ce26a6a300eee5a2 \
--experimental-control-plane --certificate-key 20366c9cdbfdc1435a6f6d616d988d027f2785e34e2df9383f784cf61bab9826

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
        

现在,在任何一个master 节点,执行kubectl get no,可以看到,集群中已经有2台master节点了

# kubectl get no
NAME       STATUS     ROLES    AGE     VERSION
master-1   NotReady   master   34m     v1.14.0
master-2   NotReady   master   4m52s   v1.14.0
  • 加入两个工作节点
分别在两个node节点操作:
kubeadm join 192.168.41.232:6443 --token ocb5tz.pv252zn76rl4l3f6 \
    --discovery-token-ca-cert-hash sha256:141bbeb79bf58d81d551f33ace207c7b19bee1cfd7790112ce26a6a300eee5a2 

再次执行kubectl get no

# kubectl  get no
NAME       STATUS     ROLES    AGE     VERSION
master-1   NotReady   master   45m     v1.14.0
master-2   NotReady   master   15m     v1.14.0
node-1     NotReady   <none>   6m19s   v1.14.0
node-2     NotReady   <none>   4m59s   v1.14.0

可以看到两个node节点都加入集群了。可是,各个节点状态为什么都是NotReady呢。通过执行kubectl describe master-1,可以看到这样的提示:

runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

原来是因为网络插件没有就绪导致的。所以 ,我们来安装一波

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

再次查看节点状态,可以看到所有节点都已经ready了。

# kubectl  get no
NAME       STATUS   ROLES    AGE    VERSION
master-1   Ready    master   134m   v1.14.0
master-2   Ready    master   104m   v1.14.0
node-1     Ready    <none>   94m    v1.14.0
node-2     Ready    <none>   93m    v1.14.0

至此,一个2主节点2工作节点的k8s集群已经搭建完毕。如果要加入更多的master或node节点,只要多次执行kubeadm join命令加入集群就好,不需要额外配置,非常方便。

token过期问题

使用kubeadm join命令新增节点,需要2个参数,--token与--discovery-token-ca-cert-hash。其中,token有限期一般是24小时,如果超过时间要新增节点,就需要重新生成token。

# 重新创建token,创建完也可以通过kubeadm token list命令查看token列表
$ kubeadm token create
s058gw.c5x6eeze28****

# 通过以下命令查看sha256格式的证书hash
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' 
9592464b295699696ce35e5d1dd155580ee29d9bd0884b*****

# 在新节点执行join
$  kubeadm join api-serverip:port --token s058gw.c5x6eeze28**** --discovery-token-ca-cert-hash 9592464b295699696ce35e5d1dd155580ee29d9bd0884b*****

集群测试

跟上篇文章minikube部署一样,这里部署一个简单的goweb服务来测试集群,运行时暴露8000端口,同时访问/info路径会显示容器的主机名。

  • 准备deployment和svc的yaml:
# deployment-goweb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb
spec:
  selector:
    matchLabels:
      app: goweb
  replicas: 4
  template:
    metadata:
      labels:
        app: goweb
    spec: 
      containers: 
      - image: lingtony/goweb
        name: goweb
        ports: 
        - containerPort: 8000
# svc-goweb.yaml
apiVersion: v1
kind: Service
metadata:
  name: gowebsvc
spec:
  selector:
    app: goweb
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 8000
  • 部署服务
kubectl apply -f deployment-goweb.yaml
kubectl  apply -y svc-goweb.yaml
  • 查看pod及服务
[root@master-1 ~]# kubectl  get po -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
goweb-6c569f884-67z89   1/1     Running   0          25m   10.244.1.2   node-1   <none>           <none>
goweb-6c569f884-bt4p6   1/1     Running   0          25m   10.244.1.3   node-1   <none>           <none>
goweb-6c569f884-dltww   1/1     Running   0          25m   10.244.1.4   node-1   <none>           <none>
goweb-6c569f884-vshkm   1/1     Running   0          25m   10.244.3.4   node-2   <none>           <none>
# 可以看到,4个pod分布在不同的node上
[root@master-1 ~]# kubectl  get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
gowebsvc     ClusterIP   10.106.202.0   <none>        80/TCP    11m
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   21h
# 暴露80端口
  • 测试访问
[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-6c569f884-bt4p6
[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-6c569f884-67z89
[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-6c569f884-vshkm
#可以看到,对SVC的请求会在pod间负载均衡。

小结

本文简单介绍了kubeadm工具原理,以及如何用它部署一个高可用的kubernetes集群。需要注意的是,kubeadm工具总体已经GA,可以在生产环境使用了。但是文中通过"kubeadm join -experimental-contaol-plane"参数增加主节点的方式,还是在alpha阶段,实际在生产环境还是用init方式来增加主节点比较稳定。kubeadm更多详细配置可以参考官方文档

查看原文

左邊__ 收藏了文章 · 2019-09-03

Kubernetes的几种主流部署方式01-minikube部署

综述

Kubernetes集群的组件众多,要部署一套符合生产环境的集群不是一件容易的事。好在随着社区的快速发展,特别是在它成为事实上的容器编排标准以后,基本所有的主流云平台都完全支持Kubernetes,或把它作为核心的云解决方案。同时,本地部署也出现了各类成熟的主动化解决方案,特别是Kubeadm,在最新的1.13版本已经官方GA了,也就是完全可以用在生产环境中了。这些云服务或自动化工具都大大减少了Kubernetes的部署难度,让运维力量不足的小型公司也能快速的搭建出可用的Kubernetes生产环境。

Kubernetes部署方案对比

Kubernetes官方文档中,总共列出了5大类,不下30种的Kubernetes安装方式。不说别的,单从数量来说,就可以看出当前Kubernetes生态的包容性和目前其他各类平台对它的技术支持有多强。文档中把部署方案分为以下几类:

  • Local-machine Solutions

可以理解为单机版的Kubernetes,非常适合入门Kubernetes学习或测试使用。代表的解决方案为Minikube。

  • Hosted Solutions
  • Turnkey – Cloud Solutions
  • Turnkey – On-Premises Solutions

这三种方式可以放在一块说,他们都是基于云服务商提供的解决方案,区别如下:

Hosted方式是指云服务商搭建的一套公共的Kubernetes,用户直接使用就好了,集群的搭建、管理、运维等操作全部都由云服务商提供,用户只要专注于自己的应用开发,不用关注集群的运维。这种解决方案特别适合小开发团队或小型公司,不仅省去了自有硬件的维护成本,连系统运维人员都可以不用了。

Turnkey–Cloud Solutions指云服务商帮忙搭建了Kubernetes Master节点,并负责维护其可用性,用户可以自定义Node节点加入集群,可以根据具体需求灵活并只用关注Node节点的维护

Turnkey–On-Premises Solutions方案是指包括Master节点和Node节点都由用户配置及维护,灵活性最高,但资源成本和运维成本也最高。
但不管上述哪种方式,云服务商都已经把Kubernetes做了一层包装,用户可以用简单的几个命令就可以部署Kubernetes集群,不需要从头开始一步步安装。

这三种不同的解决方案,阿里云的文档容器服务Kubernetes集群三种形态对比介绍的很清楚,可以对比着理解:

clipboard.png

其中,Serverless对应Hosted Solution,托管版对应Turnkey – Cloud Solution,专有版对应Turnkey – On-Premises Solution。

  • Custom Solutions

Custom安装方式顾名思义,是完全由用户自己安装维护Kubernetes,集群服务器和部署、配置、运维都由用户自己完成。这种方案灵活度最高,相对的,付出的硬件成本和部署、维护成本也最高。这里的服务器可以是类似EC2、ECS这种云主机,也可以是本地服务器、虚拟机等,甚至基于ARM的嵌入式硬件目前也能运行Kubernetes。Custom方式也是一般大公司在生产环境使用Kubernetes的最佳选择,一方面,大公司运维、开发团队人员完善,可以独立部署和运维Kubernetes集群,并且还可以根据自己的需求进行二开,整合Kubernetes容器部署、日志、监控等,打造出适合公司业务的容器平台。另一方面,很多公司考虑容器化业务的出发点之一就是可以优化公司现有的硬件资源,把原来跑物理服务器或虚拟机的业务迁移到容器平台上来,以提高自有硬件资源利用率及节省成本。现阶段,Custom部署方式除了一步步编译并部署、配置各组件,还可以通过Kubeadmin简单快速的部署出生产可用的集群。

虽然官网列出的Kubernetes部署方式很多,但也不用被这么多种部署方式搞糊涂了。所有Kubernetes集群,都少不了关键的基础组件。(参考Kubernetes概念与术语中的组件部分),不同的部署方式,无非是这些组件由云服务商部署好了,用户只要使用集群就好(Host 或 Turnkey方案),或着被做成容器运行以方便快速部署和管理(Minicube、Kubeadm等)。

Minikube 部署

简介

Minikube是由Kubernetes社区维护的单机版的Kubernetes集群,支持macOS, Linux, and Windows等多种操作系统平台,使用最新的官方stable版本,并支持Kubernetes的大部分功能,从基础的容器编排管理,到高级特性如负载均衡、Ingress,权限控制等。非常适合作为Kubernetes入门,或开发测试环境使用。Minikube实际是跑在本地的虚拟机中的,所以,需要先安装一套Hypervisor。这里以VirtualBox为例。

部署步骤

环境

  • OS:macOS Mojave
  • Hypervisor:VirtualBox 6.0

Minikube的诞生的初衷就是为了能快速部署一个单机Kubernetes集群,所以,整个部署非常简单,就2条命令搞定:

brew cask install minikube
minikube start

brew cask install直接从官方下载了minikube程序,并加入环境变量。minikube start虽然只是一条命令,但其实执行了很多步骤,命令执行后输出如下:

$ minikube start
o   minikube v0.35.0 on darwin (amd64)
>   Creating virtualbox VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
-   "minikube" IP address is 192.168.99.100
-   Configuring Docker as the container runtime ...
-   Preparing Kubernetes environment ...
@   Downloading kubeadm v1.13.4
@   Downloading kubelet v1.13.4
-   Pulling images required by Kubernetes v1.13.4 ...
-   Launching Kubernetes v1.13.4 using kubeadm ... 
:   Waiting for pods: apiserver proxy etcd scheduler controller addon-manager dns
-   Configuring cluster permissions ...
-   Verifying component health .....
+   kubectl is now configured to use "minikube"
=   Done! Thank you for using minikube!

可以看到,minikube start主要做了这些事:

  1. 创建了名为minikube的虚拟机,并在虚拟机中安装了Docker容器运行时。(实际就是Docker-machine)
  2. 下载了Kubeadm与Kubelet工具
  3. 通过Kubeadm部署Kubernetes集群
  4. 进行各组件间访问授权、健康检查等工作
  5. 在用户操作系统安装并配置kubectl

所以,minikube实际上是基于Kubeadm工具来部署Kubernetes的,我们通过minikube ssh命令可以进入部署的虚拟机中,看下里面在跑的容器:

clipboard.png

有木有看到很多熟悉的身影,有Master节点的组件kube-apiserver、kube-scheduler、kube-controller、etcd 容器,以及Node节点的kube-proxy容器,还有些附加的组件比如Coredns等。没错,Kubeadm实际就是把Kubernetes各个组件都容器化了(除了kubelet),而minikube再用虚拟机把它们都跑在一起。关于Kubeadm,下一篇文章会详细再介绍。

集群测试

Minikube成功运行以后,就已经在用户操作系统中安装了kubectl,并将运行的集群变量设置为了minkube,可以通过kubectl config view 命令查看当前的配置:

clipboard.png
kubectl的作用集群已经被指定为minikube的虚拟机了。执行kubectl get node -o wide确认Kubernetes集群节点信息。

clipboard.png
集群名称为minikube,只有一个master节点。

下面我们部署一个简单的goweb服务,该容器运行时会暴露8000端口,同时访问/info路径会显示容器的主机名。服务由3个容器实例构成,并且通过Nodeport方式暴露给用户。

// 创建一个名为goweb的Deployment,使用lingtony/goweb镜像,暴露8000端口,副本pod数为3
$ kubectl run goweb --image=lingtony/goweb  --port=8000 --replicas=3
// 查看创建的对象,可以看到已经有3个pod在运行了
$ kubectl get deployment 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
goweb   3/3     3            3           2m59s
$ kubectl get po        
NAME                     READY   STATUS    RESTARTS   AGE
goweb-8559474b8c-rphcs   1/1     Running   0          3m2s
goweb-8559474b8c-wzvsl   1/1     Running   0          3m2s
goweb-8559474b8c-xxtlz   1/1     Running   0          3m2s
// 创建svc,通过Nodeport方式暴露服务
$ kubectl expose deployment goweb --name=gowebsvc --port=80  --target-port=8000  --type=NodePort
service/gowebsvc exposed
// 查看svc,可以看到NodePort随机分配的端口为31543
$ kubectl get svc            
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
gowebsvc     NodePort    10.108.29.53   <none>        80:31534/TCP   3s
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        7h58m

接下来,在用户操作系统就可以通过minikube虚拟机的ip地址:31543来访问这个gowebsvc了,gowebsvc会把80口的请求再负载均衡到实际的goweb pod上。更方便的,可以使用minikube server命令直接获取到svc的访问地址:

// 通过minikube server命令获取svc地址
$ minikube service gowebsvc  --url
http://192.168.99.100:31534
// 测试访问一下

clipboard.png

可以看到,每次的访问请求是都进入不同的pod,与kubectl get po命令所示的pod一致。

开启Kubernetes dashboard

可以通过minikube dashboard命令直接开启dashboard

clipboard.png
macOS会自动在你的默认浏览器打开,可以通过web查看和管理集群了。

clipboard.png

小结

本文介绍了Kubernetes不同部署方式的区别,同时详细说明了minikube这个单节点Kubernetes工具的部署步骤、以及对部署后的集群做了简单测试。通过上面的部署分析可以看出,minikube的核心实际还是依靠kubeadm这个工具来部署集群的,后面的文章会介绍如何用Kubeadm部署一个多节点集群。

查看原文

左邊__ 收藏了问题 · 2018-06-20

GitLab-webhook-PHP 详解 GitLab Webhooks 自动部署应用服务器

  1. 在实际项目目录克隆远程仓库

  2. 在项目目录克隆Gitlab Web Hook For PHP

  3. 配置Gitlab项目Webhooks

https://github.com/bravist/gi...

左邊__ 提出了问题 · 2018-06-13

gitlab 10.8.3 设置webhook提示Requests to localhost are not allowed

gitlab 10.8.3 设置webhook,点击“Test”出现下列提示:

Hook execution failed: URL 'http://192.168.20.202:8082/project/myproject' is blocked: Requests to localhost are not allowed

gitlab deploy keys中有添加了id_rsa.pub 公钥

jenkins中也有添加了id_rsa 私钥和gitlab API token

关注 2 回答 1

左邊__ 关注了用户 · 2018-05-29

RancherLabs @rancher

Rancher是业界顶尖的企业级容器管理平台,是业界首个且唯一可以管理所有云上、所有发行版、所有Kubernetes集群的平台。解决了生产环境中企业用户可能面临的基础设施不同的困境,改善Kubernetes原生UI易用性不佳以及学习曲线陡峭的问题,是企业落地Kubernetes的不二之选。目前已有超过一亿次下载,超过20000家企业客户。

关注 475

左邊__ 关注了用户 · 2018-03-26

firim @fir

fir.im是国内首家提供 App 测试托管分发服务的公司,提供两步发布测试应用的 fir.im, 崩溃分析 BugHD, 持续集成 flow.ci 等一系列开发测试效率提升服务.

关注 99

左邊__ 收藏了文章 · 2018-03-22

从自动化测试到持续部署,你需要了解这些

在互联网的产品开发时代,产品迭代越来越频繁,“从功能开发完成直到成功部署”这一阶段被称为软件开发“最后一公里”。很多开发团队也越来越认识到,自动化测试和持续部署可帮助开发团队提高迭代效率和质量。

那么,如何更好地解决“最后一公里”这一问题呢?

一切从自动化测试开始,让自动化测试贯穿在整个项目开发-集成-部署-交付的-开发流程中。

如果你的团队还没有开始自动化测试,推荐从经典的测试金字塔开始。

自动化测试


在这个分层自动化测试金字塔中,Unit 代表单元测试,Service 代表服务集成测试,UI 代表页面级的功能测试。不同的产品层次都需要自动化测试,投入的精力和工作量会有所不同。下面我们仔细看下每个层次的测试:

1.1 Unit 单元测试

“凡是不能量化的工作都是不可考量的”

目前很多公司已经意识到了单元测试的重要性,但国内坚持写单元测试的团队并不多,其中一个难点在于没有考量,没有很好地执行单元测试覆盖率检测。

想想,如果没有单元测试覆盖率检测,单纯的只写单元测试,时间长了也许开发人员会产生惰性,比如:今天任务太紧了,就不写单元测试了,以后再补,反正写不写也没有人知道。引入单元测试覆盖率检测之后,开发人员会更主动地写单元测试,就算补写单元测试也更有成就感。单元测试覆盖率检测有现成的第三方工具,比如 code climate 、 Coveralls 等等,针对不同的语言也有还有一些定制化的检测工具, 比如前端常用的 Eslint , Python 常用的PEP8 等等。整个项目的单元测试覆盖情况百分比,看上去一目了然。

相比其他层级的测试,单元测试发现并解决问题付出的成本相对来说最低,而投入产出比最高。单元测试的责任主体一般来说是开发人员,写单元测试也是开发人员对自己的代码进行检查的过程。

1.2 Service 集成测试

“多数应用和产品都需要与外部资源交互,有时候多数 Bug 并不来源于程序本身,而是由从外部输入的数据所引起的。”

这时候,就更需要集成测试。

集成测试是在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。这个集成测试阶段主要解决的是检查各个软件组成单元代码是否符合开发规范、接口是否存在问题、整体功能有无错误、界面是否符合设计规范、性能是否满足用户需求等等。

集成测试与单元测试最大的区别在于,它需要尽可能地测试整个功能及相关环境。如果不经过单元测试,那么集成测试的效果将会受到很大影响,大幅增加单元代码纠错的代价。

这一层的被测对象是抽离了展现层的代码(前端以及部分后端展现层逻辑),主要是由测试人员进行,是测试人员大展身手的地方。

1.3 UI 系统测试

“一份永远都运行成功的自动化测试用例是没有价值的。一切都在变化中。”

在做好上面两层的测试覆盖之后,最顶端的是 UI 层的自动化测试。目前,UI 层的自动化覆盖正在逐渐转变为页面展示逻辑及界面前端与服务展现层交互的集成验证。UI层自动化做的方式很多,根据不同的系统,不同的架构可能会用到不同的框架或者工具,比较主流的有QTP,Robot Framework、watir、selenium 等。

怎么选择合适的工具?每个测试工具都有它的优缺点,每个被测试的项目也有自己本身的特点。比如,项目是用什么语言编写的,C, C++, Java, PHP , Python or C#? 项目是什么类型,Desktop , Web or Mobile Application? 很难说一种工具就可以搞定所有或者大部分的项目,也很难说一个项目就能单纯的靠一种工具来搞定。

UI 层是直接面向用户的,需要测试人员放入更多的时间和精力。如今的互联网公司大多需求变化大而快,迭代频繁,所以很多团队做 UI 自动化测试投入较大精力,却迟迟见不到效果,自动化测试人员每天奔命于维护脚本,追赶进度。有 2 点 UI层自动化覆盖的原则非常有必要提下:

  • 能在底层做自动化覆盖,就尽量不在UI层做自动化覆盖;

  • 只做最核心功能的自动化覆盖,脚本可维护性尽可能提高。

综上所述,分层自动化测试侧重不同,效果不尽然完美的,而最快速高效发现 bug 的方法是将自动化测试包含到构建过程中。谨慎周全的自动化测试可以进一步保证持续部署的稳定与安全,提高持续部署的成功率。

持续部署

对于持续部署,@湾区日报 这样评论:

一个团队工程技术水平高低,直接反映在部署代码上。我碰到其他公司的人,都喜欢问你们怎么部署代码的,非常大开眼界。你很难相信,很多(有一定规模的)公司仍然是人肉 SSH 到十几、二十台机器上 git pull、手动重启服务器,部署一次代码几个小时 -- 这么原始,活该加班:)

持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,毕竟快速运转的互联网公司人力成本会高于机器,投资机器优化开发流程化相对也提高了人的效率,让 engineering productivity 最大化。

2.1 持续部署的步骤

“持续部署”的痛苦源于部署时的各方面,比如需要部署到哪些环境,测试环境?灰度发布?正式环境?还有其依赖包的版本,环境配置管理等等,都需要考虑在其中。对于一个标准的部署——安装软件包并启动环境,可能的步骤将会是:

2.2 CI 工具的选择与使用

imothy写过一篇文章介绍了 IMVU 是如何进行持续部署。IMVU 的做法是,在持续集成构建过程中进行大量的、覆盖范围广的、非常可靠的自动化测试,保证在 10 分钟内跑完整个测试套件。所有测试通过后,部署便开始了。

在这个过程中,持续集成工具的选择和系统的搭建显得尤为重要。面对众多的 CI 工具,我们将其分为 Hosted CI 和 Self Hosted CI:

  • Self HostedCI 指的是将软件部署在公司的机房或内网中,需要提供多台服务器来完成 CI 系统的运转,同时需要对不同机器之间进行环境配置。主流工具有Jenkins,其他受欢迎的工具比如 Baboom 及 TeamCity 等。

  • Hosted CI 指的是由 SaaS 型的 CI 服务,全程在线进行构建配置,不需要考虑装机器,装软件,环境搭建等成本。常见的有 CircleCI,Codeship 和 TravisCI 等。

我们对比一下这两种 CI 服务:

  • Self Hosted CI 对构建环境有完全的控制权,能够实现完全定制。但需要搭建环境和配置、维护成本高,需要买专门的机器,花费人力物力且更新迁移风险高;

  • Hosted CI 无需额外机器,几分钟就可以用起来。可以根据你的需要动态调度资源。省时,省心,省力。

我们做了一款 Hosted CI 产品—— flow.ci ,它是融入了 workflow 机制的持续集成(CI)服务,也可以理解为自动化流程平台,除了集成代码、编译、测试之外,还可以集成常用的工具、灵活自定义流程。1 分钟即可完成开发测试环境搭建,开启第一个Build。


flow.ci 更侧重于工作流的设置,默认的工作流可以自动编译测试代码,进行单元测试覆盖率,代码质量检测等工具以插件的形式进行集成;并加入了 Webhook 功能。从自动化测试到持续部署,一切简单灵活。

2.3 让持续部署成功的要点

一个持续集成 & 持续部署的自动化系统并不是那么简单的事,如果不选用其他 CI 服务,其开发工作量和一个标准的大型互联网业务系统没什么两样。如果没有持续部署的经验,要想成功地进行持续部署要注意这些:

  • 充分而广泛的自动化测试覆盖;

  • 尽可能短的测试反馈时间;

  • 部署过程自动化;

  • 部署过程要保证数据安全;

  • 在稳定的前提下,尽早部署;

  • 完善的风险缓解措施;

  • 将同样的产物部署到不同的环境中

2.4 持续部署习惯的养成

持续部署真正困难的不是技术的实现,也不是工具的选择和使用,最难的是培养团队持续部署的习惯以及工程文化。可以参考下Instagram 的持续部署工程文化

总结

不论是自动化测试,还是持续部署,都只是一种实现手段;他们真正存在的价值在于提高代码质量和提高产品的持续交付能力。关于如何进行更好地进行自动化测试和持续部署,可以多参考下其他公司的持续部署实践案例与经验。

如果你有更加深刻的见解,欢迎留言交流!

【参考链接】

查看原文

左邊__ 收藏了文章 · 2018-03-01

谈谈持续集成,持续交付,持续部署之间的区别

经常会听到持续集成,持续交付,持续部署,三者究竟是什么,有何联系和区别呢?


假如把开发工作流程分为以下几个阶段:

编码 -> 构建 -> 集成 -> 测试 -> 交付 -> 部署

正如你在上图中看到,「持续集成(Continuous Integration)」、「持续交付(Continuous Delivery)」和「持续部署(Continuous Deployment)」有着不同的软件自动化交付周期。

持续集成

持续集成是指软件个人研发的部分向软件整体部分交付,频繁进行集成以便更快地发现其中的错误。“持续集成”源自于极限编程(XP),是 XP 最初的 12 种实践之一。

CI 需要具备这些:

  • 全面的自动化测试。这是实践持续集成&持续部署的基础,同时,选择合适的自动化测试工具也极其重要;

  • 灵活的基础设施。容器,虚拟机的存在让开发人员和 QA 人员不必再大费周折;

  • 版本控制工具。如 Git,CVS,SVN 等;

  • 自动化的构建和软件发布流程的工具,如 Jenkins,flow.ci

  • 反馈机制。如构建/测试的失败,可以快速地反馈到相关负责人,以尽快解决达到一个更稳定的版本。

持续集成的优点

  • “快速失败”,在对产品没有风险的情况下进行测试,并快速响应;

  • 最大限度地减少风险,降低修复错误代码的成本;

  • 将重复性的手工流程自动化,让工程师更加专注于代码;

  • 保持频繁部署,快速生成可部署的软件;

  • 提高项目的能见度,方便团队成员了解项目的进度和成熟度;

  • 增强开发人员对软件产品的信心,帮助建立更好的工程师文化。

持续集成,该从何入手

最重要的一环是选择合适的持续集成系统。是搭建私有部署还是选择托管型持续集成系统,关键在于团队运行的基础设施,团队对持续集成系统的资源投入力度。

对比一下私有部署和托管型持续集成系统,或许能帮助你更好地做出选择。

  • Self Hosted CI 指的是将软件部署在公司的机房或内网中,需要提供多台服务器来完成 CI 系统的运转,同时需要对不同机器之间进行环境配置。比如Maven 或 Gradle 或 Jenkins ,他们的特点是自由开源,且文档支持广泛。优点在于对构建环境有完全的控制权,能够实现完全定制。但需要搭建环境和配置、维护成本高,需要买专门的机器,花费较多人力物力且更新迁移风险高;

  • Hosted CI 指的是由 SaaS 型的 CI 服务,全程在线进行构建配置,不需要考虑装机器,装软件,环境搭建等成本。常见的有 CircleCI,Codeship 和 TravisCI 等,还有国内最新的持续集成服务——flow.ci 。SaaS 型的 CI 的特点在于无需额外机器,几分钟就可以用起来。可以根据你的需要动态调度资源。省时,省心,省力。

整体而言,Jenkins 过去一直是大部分公司的选择,但这个现象正在发生改变,随着公有云服务、Docker,SaaS 的普及,越来越多的企业开始选择 Hosted CI,也就是托管型持续集成系统。

另外,在选择合适的持续集成服务时,还需要考量系统的灵活度以适应公司不同阶段的开发测试需求。

选择持续集成系统只是持续集成应用的其中一步,还需要建立合适的持续集成文化比如代码质量管控、测试文化等。做好持续集成,可为持续交付与持续部署打好坚实基础。

持续交付

持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境」(production-like environments)中。持续交付优先于整个产品生命周期的软件部署,建立在高水平自动化持续集成之上。

试想想,如果说等到所有东西都完成了才向下个环节交付,导致所有的问题只能再最后才爆发出来,解决成本巨大甚至无法解决。比如,我们完成单元测试后,可以把代码部署到连接数据库的 Staging 环境中进行更多的自动化测试。如果代码没有问题,可以继续手动部署到生产环境中。当然,持续交付并不是指软件每一个改动都要尽快部署到产品环境中,它指的是任何的代码修改都可以在任何时候实施部署。

持续交付的好处

持续交付和持续集成的优点非常相似:

  • 快速发布。能够应对业务需求,并更快地实现软件价值。

  • 编码->测试->上线->交付的频繁迭代周期缩短,同时获得迅速反馈;

  • 高质量的软件发布标准。整个交付过程标准化、可重复、可靠,

  • 整个交付过程进度可视化,方便团队人员了解项目成熟度;

  • 更先进的团队协作方式。从需求分析、产品的用户体验到交互 设计、开发、测试、运维等角色密切协作,相比于传统的瀑布式软件团队,更少浪费。

持续部署

持续部署是指当交付的代码通过评审之后,自动部署到生产环境中。持续部署是持续交付的最高阶段。这意味着,所有通过了一系列的自动化测试的改动都将自动部署到生产环境。它也可以被称为“Continuous Release”。

为什么说持续部署是理想的工作流程?

“开发人员提交代码,持续集成服务器获取代码,执行单元测试,根据测试结果决定是否部署到预演环境,如果成功部署到预演环境,进行整体验收测试,如果测试通过,自动部署到产品环境,全程自动化高效运转。”

实际上,产品在从需求到部署的过程中,会经历若干种不同的环境,例如 QA 环境、各种自动化测试运行环境、生产环境等。这些环境的搭建、配置、管理,产品在不同环 境中的具体部署,状况是比较非常复杂的,从头到尾地全自动持续部署的确困难。那么,如果能做到持续交付,保证代码在模拟环境没问题,也许团队成员做到真正的心理有数。

持续部署的优点

持续部署主要好处是,可以相对独立地部署新的功能,并能快速地收集真实用户的反馈。

“You build it, you run it”,这是 Amazon 一年可以完成 5000 万次部署,平均每个工程师每天部署超过 50 次的核心秘籍。

最后

「持续集成(Continuous Integration)」、「持续交付(Continuous Delivery)」和「持续部署(Continuous Deployment)」提供了一个优秀的 DevOps 环境,对于整个团队来说,好处与挑战并行。无论如何,频繁部署、快速交付以及开发测试流程自动化都将成为未来软件工程的重要组成部分。

欢迎分享你的观点。

【参考文章】

查看原文

左邊__ 收藏了文章 · 2018-02-08

ubuntu17.10设置固态ip

本文首发于我的博客

设置了基本的环境之后,需要设置固定的ip,要不然每次启动都变IP,我每次调整IP都得疯了。

在Ubuntu 17.10 中,使用了一种新的命令来配置静态IP。

对此,我们需要修改的是vim /etc/netplan/01-netcfg.yaml

我们先看看该文件的内容和格式:

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    ens33:
      dhcp4: yes

我们可以看到这里设置的dhcp4yes。表示是dhcp模式。

好了,下面我们要进行修改了。下面是改好的格式:

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    ens33:
      dhcp4: no
      dhcp6: no
      addresses: [192.168.110.231/24]
      gateway4: 192.168.110.1
      nameservers:
          addresses: [114.114.114.114, 8.8.8.8]

现在我们解释一下修改的内容:

  • dhcp4:ipv4的自动分配,设置为no表示不进行ipv4地址的自动分配
  • dhcp6:ipv6的自动分配,设置为no表示不进行ipv6地址的自动分配
  • addresses:设置固定的ip。这里有个/24,我们需要对这一块单独说下。
  • gateway4:网关地址。
  • nameservers: DNS服务器。addresses的数组表示可以设置多个。

如果有人设置过windows的静态IP或者说之前的版本的ubuntu的静态ip的,可能会觉得少了一个东西,没错,就是子网掩码。

这里就是说的/24了。它其实就是设置的子网掩码。下面有前缀对应的ip,我们可以通过这个来进行响应的设置了。

前缀大小子网掩码
/24255.255.255.0
/25255.255.255.128
/26255.255.255.192
/27255.255.255.224
/28255.255.255.240
/29255.255.255.248
/30255.255.255.252

好了,我们把配置文件的内容按照实际情况修改好了之后。执行以下命令进行部署:

sudo netplan apply

如果没有问题,固态ip就设置成功了。然后我们重新配置我们xshell登录的ip,重新就进行登录就可以了。

好了,是不是非常简单呢?

查看原文

左邊__ 提出了问题 · 2017-12-26

ubuntu运行sudo dpkg -i安装文件,总是提示:Corrent Java version found

$ sudo apt-get install jenkins
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
jenkins 已经是最新的版本。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 6 个软件包未被升级。
有 2 个软件包没有被完全安装或卸载。
解压缩后会消耗掉 0 B 的额外空间。
您希望继续执行吗? [Y/n] y
正在设置 oracle-java8-set-default (8u151-1~webupd8~0) ...
正在设置 jenkins (2.97) ...
Correct java version found

以下为己安装的Java版本
$ java -version

java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

关注 2 回答 1

认证与成就

  • 获得 0 次点赞
  • 获得 21 枚徽章 获得 0 枚金徽章, 获得 8 枚银徽章, 获得 13 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-11-10
个人主页被 194 人浏览