k8s部署应用(以nginx为例)

Posted by walikrence on July 29, 2019

k8s部署应用(以nginx为例)

概念

deploy

A Deployment controller provides declarative updates for Pods and ReplicaSets.

deploy 提供一个更新pod 和 replicasets的更新说明

You describe a desired state in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.

通俗来讲就是你可以声明你需要多少个,什么样的pod,写一个yaml告诉集群,集群自动帮你实现

service

An abstract way to expose an application running on a set of Pods as a network service.

service 是一个抽象的,用来expose 已经创建的pods的 对象。 client通过访问service来访问一组pods中的某一个pod

With Kubernetes you don’t need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.

你也可以不使用service而直接指定使用某个pod,但是这样并不推荐。

Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过 ReplicaSets 能够动态地创建和销毁 Pod(例如,需要进行扩缩容,或者执行 滚动升级)。 每个 Pod 都会获取它自己的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。 这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 Pod 中的哪些 backend 呢?

关于 Service

Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector(查看下面了解,为什么可能需要没有 selector 的 Service)实现的。

举个例子,考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪个 backend 副本。 然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不应该也没必要知道,而且也不需要跟踪这一组 backend 的状态。 Service 定义的抽象能够解耦这种关联。

示例

deploy

# nginx-deployment.yaml
apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment #这个随便起
spec:
  replicas: 3 #重复的份数
  template: #每一份pod长什么样子
    metadata:
      labels: # 标签,用来跟service 匹配
        app: nginx
    spec:
      containers: #使用的容器
      - name: nginx
        image: nginx:1.7.9 # 镜像版本
        ports:
        - containerPort: 80 # 容器端口

部署

kubectl create -f nginx-deployment.yaml --record

查看

kubectl get deployments
kubectl get rs
kubectl get pods

修改

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

service

# my-service.yml
kind: Service
apiVersion: v1
metadata:
  name: my-service    #名字,这个随便写
spec:
  selector:      #选择器
    app: MyApp   #标签,用来选择对应的pod
  ports:
    - protocol: TCP         #协议
      port: 80         #端口号
      targetPort: 9376       #target端口号

部署

kubectl create -f my-service.yaml 

查看

kubectl get service 
#或者
kubectl get svc

nginx 部署

部署一个两份pod的deploy,每个pod包含一个nginx容器

# a.yml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template: # create pods using pod definition in this template
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx     # 定义使用的docker镜像,镜像必须在本地存在或者存在于仓库
          ports:
            - containerPort: 80


定义service,通过 NodePort方式把服务映射到任意节点的 30003端口,即可通过任意节点的ip加端口号访问服务

# b.yml
kind: Service
apiVersion: v1
metadata:
  name: nginx
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30003
  selector:
    app: nginx

部署

kubectl create -f a.yml
kubectl create -f b.yml

查看

kubectl get svc
kubectl get pod
kubectl get deploy
kubectl get rs
#或者使用dashboard图形化界面查看

访问我们部署的nginx

初始状态

我们在minikube上部署了nginx, 我们的架构是 服务器-》服务器创建的VM-〉VM上面运行的集群

所以我们要访问集群需要先登陆节点,然后通过

kubectl cluster-info

获得节点的ip地址

再通过

curl <节点ip地址>:30003 

或者浏览器打开<节点ip地址>:30003 来访问我们部署的nginx应用。

改进

当然我们用户不能ssh我们的服务器再在服务器上执行这么多命令。

所以我们在我们的节点上配置一个反向代理

反向代理

#安装nginx
sudo apt install nginx -y

修改 nginx.conf文件,Ubuntu位于 /etc/nginx/nginx.conf

events {
  worker_connections  4096;  ## Default: 1024
}
http {
    server {
            listen  80;
            server_name 0.0.0.0;
 
 
            location / {
                    proxy_pass http://<节点的ip地址>:30003;
            }
            
    }
}

例如

events {
  worker_connections  4096;  ## Default: 1024
}
http {
    server {
            listen  80;
            server_name 0.0.0.0;
 
 
            location / {
                    proxy_pass http://192.168.99.102:30003;
            }
            
    }
}

然后

nginx -s reload

更新配置

此时我们就成功设置了反向代理。所有指向我们服务器80端口的请求都会被代理到节点的30003端口,也就是我们刚刚部署的nginx应用。

此时我们就可以通过服务器的ip地址在任意电脑上访问我们刚刚部署的nginx应用了。

把dashboard代理出来

#启动dashboard
minikube dashboard

此时dashboard已经激活在30000端口,我们可以通过反向代理将dashboard代理出来

假设我们节点的ip地址为192.168.99.102,修改nginx.conf

events {
  worker_connections  4096;  ## Default: 1024
}
http {
    server {
            listen  80;
            server_name 0.0.0.0;
 
 
            location / {
                    proxy_pass http://192.168.99.102:30003;
            }
            
    }
    server {
            listen  8080;
            server_name 0.0.0.0;
 
 
            location / {
                    proxy_pass http://192.168.99.102:30000;
            }
            
    }
}

更新nginx配置

nginx -s reload

此时我们就把dashboard图形化界面反向代理出来了,就可以在其他主机上通过 <服务器ip>:8080 访问图形化管理界面