-
Java Web应用:
-
是一个运行在 tomcat里的 Web App,如图1.1所示,JSP页面通过JDBC直接访问 MYSQL数据库并展示数据。为了演示和简化的目的,只要程序正确连接到了数据库上,它就会自动完成对应的 Table的创建与初始化数据的准备工作。所以,当我们通过浏览器访问此应用的时候,就会显示一个表格的页面,数据则来自数据库。
-
此应用需要启动两个容器: Web App容器和 MYSQL容器,并且 Web App容器需要访问MYSQL容器。在 Docker I时代,假设我们在一个宿主机上启动了这两个容器,则我们需要把MYSQL容器的IP地址通过环境变量的方式注入 Web App容器里;同时,需要将 Web App容器的8080端口映射到宿主机的8080端口,以便能在外部访问。
-
安装好k8s,启动好各种服务后,首先为MySQL服务创建一个RC定义文件:mysql-rc.yaml
apiVersion: v1 kind: ReplicationController #副本控制器RC metadata: name: mysql #RC的名称,全局唯一 spec: replicas: 1 #Pod副本期待数量 selector: app: mysql #符合目标的pod拥有此标签 template: #根据此模板创建pod的副本(实例) metadata: labels: app: mysql #pod副本拥有的标签,对应RC的Selector spec: containers: #pod内容起的定义部分 - name: mysql #容器的名称 image: registry:5000/pre_images/mysql:5.5 #容器对应的docker image ports: - containerPort: 3306 #容器暴露的端口号 env: #注入到容器内的环境变量 - name: MYSQL_ROOT_PASSWORD value: "123456"
-
yaml定义文件中的kind属性,用来表明此资源对象的类型,比如这里的值为“ Replication Controller,表示这是一个RC;
-
spec一节中是RC的相关属性定义,比如spec. selector是RC的Pod标签( Label)选择器,即监控和管理拥有这些标签的Pod实例,确保当前集群上始终有且仅有 replicas个Pod实例在运行,这里我们设置 replicas=1表示只能运行一个 MYSQLPod实例。
-
当集群中运行的Pod数量小于 replicas时,RC会根据 spec.template一节中定义的Pod模板来生成一个新的Pod实例, spec template. metadata.labels指定了该Pod的标签,需要特别注意的是:这里的 labels必须匹配之前的spe. selector,否则此RC每次创建了一个无法匹配 Label的Pod,就会不停地尝试创建新的Pod.
-
创建好redis-master-controller.yaml文件以后,在Master节点用命令将它发布到k8s集群中:
[root@node2 test]# kubectl create -f mysql-rc.yaml replicationcontroller/mysql created
-
查看RC和Pod
[root@node2 test]# kubectl get rc NAME DESIRED CURRENT READY AGE mysql 1 1 1 3m49s [root@node2 test]# kubectl get pods NAME READY STATUS RESTARTS AGE mysql-g2mqw 1/1 Running 0 3m49s
-
docker ps查看正在运行的容器,发现mysql容器已正常运行,除此之外,还有一个来自谷歌的pause容器,这就是pod的“根”容器。
-
然后创建一各Service——MySQL的定义文件,mysql-svc.yaml。
apiVersion: v1 kind: Service #表明是k8s Service metadata: name: mysql #Service的全局唯一名称 spec: ports: - port: 3306 #Service提供服务的端口号 selector: #Service对应的Pod拥有这里定义的标签 app: mysql
- 其中metadata.name是Service的服务名(ServiceName),port属性定义了Service的虚端口;spec.selector确定了哪些pod副本(实例)对应到本服务。类似地,我们通过kubectl create 命令创建Service对象
kubectl create -f mysql-svc.yaml
查看
[root@node2 test]# kubectl get svc | grep mysql mysql ClusterIP 10.96.114.38
3306/TCP 152m mysql服务被分配了一个虚拟地址,随后k8s集群中其他新创建的Pod就可以通过Service的Cluster IP+端口号来连接和访问它。
启动tomcat的启动,创建一个myweb-rc.yaml
apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 1 selector: app: myweb template: metadata: labels: app: myweb spec: containers: - name: myweb image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
-
注意到引用了MYSQL_SERVICE_HOST=mysql环境变量,而“MySQL”恰好是我们之前定义的MySQL服务的服务名,运行命令,完成创建和验证
kubectl create -f myweb-rc.yaml [root@node2 test]# kubectl get pods | grep myweb myweb-hlmxz 1/1 Running 0 103m
-
创建对应的Service
apiVersion: v1 kind: Service metadata: name: myweb spec: type: NodePort ports: - port: 8080 nodePort: 30001 selector: app: myweb
-
注意type=NodePort和nodePort=30001两个属性,标明此Service开启了NodePort访问的外网访问模式,在k8s集群之外,比如在本机的浏览器里,可以通过30001这个端口访问myweb9对应到8080的虚端口上)。
kubectl create -f myweb-svc.yaml [root@node2 test]# kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1
443/TCP 3d19h mysql ClusterIP 10.96.114.38 3306/TCP 165m myweb NodePort 10.107.166.10 8080:30001/TCP 139m
创建一个tomcat-deployment.yaml的Deployment描述文件,内容如下:
apiVersion: apps/v1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchexpressions: - {key: tier, operator: In, values: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080
apiVersion随版本的改变而改变:
- 1.6版本之前 apiVsersion:extensions/v1beta1
- 1.6版本到1.9版本之间:apps/v1beta1
- 1.9版本之后:apps/v1
创建Deployment
kubectl apply -f tomcat-deployment.yaml
查看Deployment
[root@node2 test]# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE frontend 1/1 1 1 9m28s
UP-TO-DATE:最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少个Pod副本已经成功升级。
AVAILABLE:当前集群中可用的Pod副本数量,即集群中当前存活的Pod数量。
运行命令查看Replica Set,可看到它的命名和Deployment名字有关系
[root@node2 test]# kubectl get rs NAME DESIRED CURRENT READY AGE frontend-797f47d685 1 1 1 13m
然后查看pod,发现pod命名以Deployment对应的Replica Set的名字为前缀,这种命名很清晰地表明了一个Replica Set创建了哪些Pod
[root@node2 test]# kubectl get pods NAME READY STATUS RESTARTS AGE frontend-797f47d685-fx466 1/1 Running 0 18mService
创建一个tomcat-service.yaml的定义文件,内容为:
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: ports: - port: 8080 selector: tier: frontend
创建
[root@node2 test]# kubectl apply -f tomcat-service.yaml
之前在tomcat-deployment.yaml里定义的Tomcat的Pod刚好拥有这个标签,所以我们刚才创建的tomcat-service已经对应到一个Pod实例,运行下面的命令可以查看tomcat-service的Endpoint列表
[root@node2 test]# kubectl get endpoints NAME ENDPOINTS AGE kubernetes 192.168.242.132:6443 5d16h tomcat-service 10.244.3.83:8080 3m55s
其中10.244.3.83是Pod的IP地址,端口8080是Container暴露的端口。
运行以下命令即可看到tomcat-service被分配的Cluster-IP:
[root@node2 test]# kubectl get svc tomcat-service -o yaml apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"tomcat-service","namespace":"default"},"spec":{"ports":[{"port":8080}],"selector":{"tier":"frontend"}}} creationTimestamp: "2021-11-25T02:21:32Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:annotations: .: {} f:kubectl.kubernetes.io/last-applied-configuration: {} f:spec: f:ports: .: {} k:{"port":8080,"protocol":"TCP"}: .: {} f:port: {} f:protocol: {} f:targetPort: {} f:selector: .: {} f:tier: {} f:sessionAffinity: {} f:type: {} manager: kubectl operation: Update time: "2021-11-25T02:21:32Z" name: tomcat-service namespace: default resourceVersion: "252606" selflink: /api/v1/namespaces/default/services/tomcat-service uid: 5aa2c1f2-008f-4229-a220-0dc5d3eb10d3 spec: clusterIP: 10.110.156.40 ports: - port: 8080 protocol: TCP targetPort: 8080 selector: tier: frontend sessionAffinity: None type: ClusterIP status: loadBalancer: {}
在spec.ports的定义中,targetPort属性用来确定提供该服务的容器所暴露(EXPOSE)的端口号,及具体业务进程在容器内的targetPort上提供TCP/IP接入,而port属性则定义了Service的虚端口。前面定义Tomcat服务的时候,没有指定targetPort,则默认targetPort与port相同。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)