使用minikube快速安装istio集群

Posted by ShenHengheng on 2019-02-22

今天带着大家如何在minikube本地kubernetes测试集群中安装和尝试部署一个服务。

本节课不教:

本节课的目标是:

  • 使用Helm或者手动方式来构建istio集群

  • 使用istio框架来部微服务

  • 服务治理与金丝雀发布等等

    23534644.png

启动minikube集群

使用下面的指令在本地启动两个节点的k8s集群,分别为master和node节点,并使node节点加入到集群中。

# 启动master节点,名字为k8s-m1
$ minikube --profile k8s-m1 start --network-plugin=cni --docker-env HTTP_PROXY=http://192.168.99.1:12333 --docker-env HTTPS_PROXY=http://192.168.99.1:12333 --docker-env NO_PROXY=127.0.0.1/24
# 以同样的方式启动node节点,名字为k8s-n1
$ minikube --profile k8s-n1 start --network-plugin=cni --docker-env HTTP_PROXY=http://192.168.99.1:12333 --docker-env HTTPS_PROXY=http://192.168.99.1:12333 --docker-env NO_PROXY=127.0.0.1/24

确认两个节点已经启动,但是现在node节点并没有加入到集群中,你可能使用下面指令会看到NotReady的标示,也有可能列表中不会出现k8s-n1的条目。

# 切换到master节点的配置中,这样才可以使用kubectl来查询资源信息
$ kubectl config --use-context k8s-m1
# 查看当前的节点列表
$ kubectl get no

这时候需要将node节点加入集群,使用下面指令获得TOKEN,并且使用kubeadm join指令,使得node节点加入集群。

# 获取master节点的ip地址
$ minikube --profile k8s-m1 ssh "ifconfig eth1"
# 获取当前的TOKEN列表
$ minikube --profile k8s-m1 ssh "sudo kubeadm token list"
# 执行下面指令进入 k8s-n1
$ minikube --profile k8s-n1 ssh
# 下面为进入 k8s-n1 VM 內执行的指令
$ sudo su -
$ TOKEN=7rzqkm.1goumlnntalpxvw0
$ MASTER_IP=192.168.99.100
$ kubeadm join --token ${TOKEN} ${MASTER_IP}:8443 \
    --discovery-token-unsafe-skip-ca-verification \
    --ignore-preflight-errors=Swap \
    --ignore-preflight-errors=DirAvailable--etc-kubernetes-manifests
# 看到以下结果后,即可以在 k8s-m1 context 来操作。...
Run 'kubectl get nodes' on the master to see this node join the cluster.

这时候我们回到我们本地的机器(非VM),通过执行下面命令确认k8s-n1已经准备完成。

# 查看当前的节点列表
$ kubectl get no

使用helm安装istio

为了方便起见,这里我使用helm chart来安装istio,这里参考了下面的文档:

1). 使用下面的命令安装helm(mac系统)

$ brew install kubernetes-helm

其他系统的安装方式请参考:
https://helm.sh/docs/using_helm/#installing-helm

这里是自动安装的,这里你安装的只是一个helm client,你需要又一个helm后端来支持helm自动化部署的功能,你也可以通过下面的命令查看当前的helm的安装情况以及版本。

$ helm version

如果出现Server端没有起来的情况,使用helm init –service-account tiller 就自动将Tiller端安装到kubernetes集群中 。

2). 下载istio并准备安装

使用下面的指令自动下载istio的最新发行版本,并解压到当前的文件夹下,这里有一个istio的客户端二进制文件,这时你需要手动的将二进制文件的目录添加到PATH环境变量中。

$ curl -L https://git.io/getLatestIstio | sh -
$ export PATH="$PATH:/Users/rh01/istio-1.0.6/bin" #这是会话环境变量的设置,临时使用,如果想永久生效,请添加到 ~/.bashrc 或者 /etc/profile中

3). 安装istioz

切换到istio的文件夹下,并使用helm 安装 install 文件夹下面的yaml 来创建istio。下面的命令是我在本地测试过的:

$ cd istio-1.0.6
$ helm template install/kubernetes/helm/istio --name istio --namespace istio-system > $HOME/istio-1.0.6/istio.yaml
$ kubectl create namespace istio-system                              # 创建istio-system命名空间,之后管理istio的所有资源
$ kubectl apply -f install/kubernetes/helm/helm-service-account.yaml # 创建helm服务账号,使得helm能够有权限对istio-system命名空间进行操作
$ kubectl apply -f install/kubernetes/helm/istio/templates/crds.yaml # 创建crd
$ kubectl apply -f $HOME/istio-1.0.6/istio.yaml                      # 创建istio所有资源对象
$ kubectl get po -n istio-system
NAME                                      READY     STATUS      RESTARTS   AGE
istio-citadel-6f444d9999-7l2hx            1/1       Running     0          1m
istio-cleanup-secrets-qjk7c               0/1       Completed   0          1m
istio-egressgateway-6d79447874-v6xds      1/1       Running     0          1m
istio-galley-685bb48846-pxcs2             1/1       Running     0          1m
istio-ingressgateway-5b64fffc9f-4jnr9     1/1       Running     0          1m
istio-pilot-8645f5655b-s6nbq              0/2       Pending     0          1m
istio-policy-547d64b8d7-vtxqh             2/2       Running     0          1m
istio-security-post-install-r27sv         0/1       Completed   0          1m
istio-sidecar-injector-5d8dd9448d-bwcvg   1/1       Running     0          1m
istio-telemetry-c5488fc49-qr7sg           2/2       Running     0          1m
prometheus-76b7745b64-pm68q               1/1       Running     0          1m

遇到的坑:等等我遇到了一个istio-pilot内存不足的情况,因为我是两个节点,但是因为是在本地创建的两个虚拟机,所有内存和CPU资源都比较小,因此当出现资源不足的时候,就Pending了,这时候需要手动修改一下请求的内存资源的大小就可以了。

使用到的命令

$ kubectl edit pods istio-pilot-xxx -n istio-system
# 修改resource的request的memory为100Mi即可

部署一个应用

这个是官方给出的一个例子 bookinfo,这个应用由四个微服务组成,下面是应用的架构图。

20190222153800_46088.png

下面的所有命令以及说明部分来自下面的文档:

下面的指令将会在kubernetes上部署一个bookinfo应用,并由istio提供微服务的一些服务调用和路由等等功能,具体的istio特性,后期见。

$ kubectl label namespace default istio-injection=enabled
namespace "default" labeled
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
service "details" created
deployment.extensions "details-v1" created
service "ratings" created
deployment.extensions "ratings-v1" created
service "reviews" created
deployment.extensions "reviews-v1" created
deployment.extensions "reviews-v2" created
deployment.extensions "reviews-v3" created
service "productpage" created
deployment.extensions "productpage-v1" created
$ kubectl get services
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.97.137.200    <none>        9080/TCP   7s
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP    56m
productpage   ClusterIP   10.106.43.117    <none>        9080/TCP   6s
ratings       ClusterIP   10.108.175.114   <none>        9080/TCP   7s
reviews       ClusterIP   10.96.73.150     <none>        9080/TCP   6s
$ kubectl get pods
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io "bookinfo-gateway" created
virtualservice.networking.istio.io "bookinfo" created
$  kubectl get gateway
NAME               AGE
bookinfo-gateway   9s
$ kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                                                   AGE
istio-ingressgateway   LoadBalancer   10.101.64.224   <pending>     80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:31643/TCP,8060:30348/TCP,853:30934/TCP,15030:32334/TCP,15031:32681/TCP   17m

这时候大家会看到istio-ingressgateway服务的EXTERNAL_IP是pending状态,这是因为我们没有指定外置的负载均衡器的ip地址,这里有三种处理方式:

  • 如果处于云服务厂商的环境,并且有负载均衡器,这时候就填写负载均衡器的ip地址
  • 如果没有,可以采取将服务的类型改为NodePort类型,或者直接使用提供的NodePort,这样就可以使用http://<Ingress所在Node的IP>:NodePort/productpage的方式访问
  • 另外你也可以将ingress对象处于的Node的ip作为ExternalIP,也是可以访问的。这样就可以直接使用http://ExternalIP:80/productpage进行访问。

具体的如何获取ingress和配置ingress,详见下面的文档
https://istio.io/docs/tasks/traffic-management/ingress/#determining-the-ingress-ip-and-ports

大功告成

屏幕快照 2019-02-22 下午3.15.31.png

如果继续刷新,会发现有三个版本的应用出现,就是红色的星星,黑色的星星,没有星星这三个版本,会随机出现,我们可以使用istio来管理这些不同版本的应用,通过金丝雀发布,灰度发布等一些高级特性实现切流量的功能,后面的文章我会详细介绍有关istio的高级特性。

屏幕快照 2019-02-22 下午3.37.12.png

屏幕快照 2019-02-22 下午3.37.39.png

Bug

devmapper: Thin Pool has 82984 free data blocks which is less than minimum required 163840 free data blocks. Create more free space in thin pool or use dm.min_free_space option to change behavior

解决办法:

  1. Cleanup exited processes:
docker rm $(docker ps -q -f status=exited)
  1. Cleanup dangling volumes:
docker volume rm $(docker volume ls -qf dangling=true)
  1. Cleanup dangling images:
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)