美文网首页程序员每天进步一点点
2020-06-09【阿里云ECS搭建minikube和Isti

2020-06-09【阿里云ECS搭建minikube和Isti

作者: 桢桢claire | 来源:发表于2020-06-09 06:56 被阅读0次
    白色的睡莲

    今日鸡汤

    在光亮中,世界始终使我们最初和最后的爱。

    愿每天太阳升起的时候,你都对这个世界存有爱意。

    最近在研究Istio1.6新特性,于是想自己搭一个试试看。计划是这样的:
    1)买一台阿里云ECS,用CentOS系统;
    2)装一个minikube,跑一个Guestbook应用验证成功;
    3)再装一个Istio1.6,跑一个Bookinfo应用验证成功。

    计划是一天弄好,但是看起来很简单的事情,还是遇到了很多问题,花了两天的时间才终于弄好,分享给各位。本文是第二篇,介绍Kubernetes示例程序验证和反向代理Ngnix的配置。

    步骤

    第三步:使用Kubernetes示例程序Guestbook测试

    Guestbook是一个PHP Web应用,包括frontend、redis-master和redis-slave三个微服务。
    其中,redis-master服务处理写请求,redis-slave服务处理读请求。
    具体配置参考Kubernetes官方文档

    1. 先用准备好的工具pull-google-container拉镜像。如何使用请参考《填坑指南->3. 如何在国内拉gcr.io、k8s.gcr.io镜像?》
      需要拉的镜像有三个:
    k8s.gcr.io/redis:e2e
    gcr.io/google_samples/gb-redisslave:v3
    gcr.io/google-samples/gb-frontend:v4
    
    1. 创建Redis Master Deployment 和 Service。Deployment里面使用redis的image,replicas设置为1。
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
    
    1. 创建Redis Slave Deployment 和 Service。Deployment里面使用gb-redisslave:v3的image,replicas设置为2。
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
    
    1. 创建Guestbook Frontend Deployment和Service。Deployment里面使用gb-frontend:v4的image,replicas设置为3。
    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
    
    1. 查看部署状态。
      使用命令查看Pod和Service的部署状态:

    pod:按照replica,部署了1个redis-master、2个redis-slave、3个frontend,可以看到他们都在 Running状态。

    [root@node2 ~]# kubectl get pod
    NAME                              READY   STATUS    RESTARTS   AGE
    details-v1-7f6df6f54-r9kjm        2/2     Running   0          35h
    frontend-678d98b8f7-248tw         1/1     Running   0          41h
    frontend-678d98b8f7-jsnw7         1/1     Running   0          41h
    frontend-678d98b8f7-k2lhn         1/1     Running   0          41h
    hello-node-bcbcd7f76-wlpql        1/1     Running   0          42h
    productpage-v1-69886c8bcb-q278z   2/2     Running   0          35h
    ratings-v1-6665bbd4db-h7zmg       2/2     Running   0          35h
    redis-master-545d695785-fvhld     1/1     Running   0          41h
    redis-slave-546fc99d45-czl25      1/1     Running   0          41h
    redis-slave-546fc99d45-hhbzl      1/1     Running   0          41h
    reviews-v1-7fd87d96bd-qkhlm       2/2     Running   0          35h
    reviews-v2-55d9bfb6d8-qk7n8       2/2     Running   0          35h
    reviews-v3-5776c54c64-6xbwv       2/2     Running   0          35h
    

    service:

    [root@node2 ~]# kubectl get svc
    NAME           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
    details        ClusterIP      10.103.152.201   <none>        9080/TCP         35h
    frontend       NodePort       10.102.61.100    <none>        80:30004/TCP     40h
    hello-node     LoadBalancer   10.106.132.76    <pending>     8080:31662/TCP   41h
    kubernetes     ClusterIP      10.96.0.1        <none>        443/TCP          43h
    productpage    ClusterIP      10.110.6.242     <none>        9080/TCP         35h
    ratings        ClusterIP      10.96.192.242    <none>        9080/TCP         35h
    redis-master   ClusterIP      10.108.247.204   <none>        6379/TCP         41h
    redis-slave    ClusterIP      10.99.55.40      <none>        6379/TCP         41h
    reviews        ClusterIP      10.98.243.11     <none>        9080/TCP         35h
    

    可以看到frontend是通过NodePort起来的,可以通过命令获得访问地址:

    [root@node2 ~]# minikube service frontend --url
    http://172.26.205.16:30004
    

    或者直接使用http://<ECS 私有ip>: 80映射端口(30004)访问即可。

    1. 测试运行状态。
      由于配了nginx转发规则,因此使用http://<公有ip>:30005来访问:
      Guestbook应用

    第四步:使用nginx映射内网IP

    由于用ECS的公网IP一直访问不到服务,于是想到用nginx做一个转发,不知道官方正解是什么,感觉每个服务都要配转发规则实在是有点儿原始。

    失败的尝试:使用nginx docker镜像

    首先想到用docker起一个nginx container,在里面配置转发规则。

    docker pull nginx
    docker run -d -p 8080:80 --name nginx-web -v /root/nginx/www:/usr/share/nginx/html -v /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/logs:/var/log/nginx nginx
    docker start nginx-web
    

    还是访问不到,我猜是请求直接转发到container内部,但是想要访问的服务并不是起在容器内部,所以访问不到(不知道我的猜测对不对)。

    于是放弃docker的方式,选择直接在ECS里安装nginx。

    使用服务器版nginx

    1. 添加源
    rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    
    1. 安装Nginx
    yum install -y nginx
    
    1. 修改nginx.conf文件,添加转发规则
      在http标签下增加server定义,对需要转发服务的端口定义监听端口和目标路径:
        server {
            listen       8080 default_server;
            listen       [::]:8080 default_server;
            server_name  _;
            root         /usr/share/nginx/html;
    
            # Load configuration files for the default server block.
            include /etc/nginx/default.d/*.conf;
    
            location / {
            }
    
            error_page 404 /404.html;
                location = /40x.html {
            }
    
            error_page 500 502 503 504 /50x.html;
                location = /50x.html {
            }
        }
    
        upstream frontend {
            server 172.26.205.16:30004;
        }
    
        upstream ingress{
            server 172.26.205.16:32642;
            server 172.26.205.16;
        }
    
        server {
            listen       30005 default_server;
            listen       [::]:30005 default_server;
            server_name  _;
            location / {
            proxy_pass http://frontend;
            }
        }
    
        server {
            listen       31663 default_server;
            listen       [::]:31663 default_server;
            server_name  _;
            location / {
                proxy_pass http://172.26.205.16:31662;
            }
        }
    
        server {
            listen       32643 default_server;
            listen       [::]:32643 default_server;
            server_name  _;
            location /productpage {
                proxy_pass http://ingress;
            proxy_http_version 1.1;
            }
            location ~ .* {
                proxy_pass http://ingress;
                proxy_http_version 1.1;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
        }
    
    1. 启动ngnix并设置开机自动运行
    systemctl start nginx.service
    systemctl enable nginx.service
    

    下一篇将介绍Istio1.6安装和示例程序Bookinfo的配置。

    填坑指南

    1. 如何在国内拉gcr.io、k8s.gcr.io镜像?

    使用官方命令启动k8s应用一直卡在init阶段,查看event发现拉镜像失败。
    原因:
    k8s的镜像默认都是从谷歌拉,由于科学上网,只能借助开源项目https://github.com/anjia0532/gcr.io_mirror 拉镜像,再手动tag。

    解决办法:
    参照https://cloud.tencent.com/developer/article/1353088
    1)添加pull-google-container工具脚本 pull-google.sh:

      image=$1
      echo $1
      img=`echo $image | sed 's/k8s\.gcr\.io/anjia0532\/google-containers/g;s/gcr\.io/anjia0532/g;s/\//\./g;s/ /\n/g;s/_/-/g;s/anjia0532\./anjia0532\//g' | uniq | awk '{print ""$1""}'`
      echo "docker pull $img"
      docker pull $img
      echo  "docker tag $img $image"
      docker tag $img $image
    ~                           
    

    2)放到/usr/local/bin下面:

    chmod +x  pull-google.sh && cp  pull-google.sh /usr/local/bin/pull-google-container
    

    3)使用pull-google-container命令,他直接做好image名称替换->拉image->打标签,非常省心。

    pull-google-container gcr.io/google-samples/gb-frontend:v4
    gcr.io/google-samples/gb-frontend:v4
    docker pull anjia0532/google-samples.gb-frontend:v4
    v4: Pulling from anjia0532/google-samples.gb-frontend
    Digest: sha256:aaa5b327ef3b4cb705513ab674fa40df66981616950c7de4912a621f9ee03dd4
    Status: Image is up to date for anjia0532/google-samples.gb-frontend:v4
    docker tag anjia0532/google-samples.gb-frontend:v4 gcr.io/google-samples/gb-frontend:v4
    

    2. 如何修改IngressGateway类型?

    如果想将LoadBalancer的类型切换到nodeport,可通过这个命令设置:
    kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
    之后通过私有IP+80端口的形式使用HTTP访问。

    3. nginx反向代理返回HTTP 426状态码?

    HTTP/1.1 426 Upgrade Required
    Upgrade: HTTP/2.0
    Connection: Upgrade

    原因:
    nginx反向代理默认走http 1.0版本,但是被反向代理的container走的是1.1版本

    解决办法:
    转发处配置支持http1.1

    4. nginx反向代理刷不出css怎么办?

    原因:
    只对/productpage路径下的资源进行了转发,css、js等资源不在该路径下就找不到了。

    解决办法:
    配置proxy_set_header增加对css和js等资源的转发。

    server {
            listen       32643 default_server;
            listen       [::]:32643 default_server;
            server_name  _;
    
            location /productpage {
                proxy_pass http://productpage_p;
                proxy_http_version 1.1;
            }
    
            location ~ .* {
                proxy_pass http://productpage_p;
                proxy_http_version 1.1;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
        }
    

    5. istiod是什么?

    istiod 是一个单体应用,它用较低的复杂性提供了和之前版本一致的功能。组成旧版控制平面的服务都还以子模块的方式存在于项目之中,但提供了更好的运维体验。操作者只需关注单一二进制文件的运行和升级了。简言之,把之前复杂的控制面组件(Pilot、Gallery、Injector、Mixer和Citadel)作为内部子模块放到istiod里。

    有两篇文章对istiod的内容作了介绍,讲的挺好,推荐看一下:
    (译)Istiod——回到单体的理由
    Service Mesh 化繁为简: 基于 Istiod 回归单体设计

    相关文章

      网友评论

        本文标题:2020-06-09【阿里云ECS搭建minikube和Isti

        本文链接:https://www.haomeiwen.com/subject/rulltktx.html