1、步驟梳理
本章節(jié)將主要圍繞實(shí)戰(zhàn)搭建項(xiàng)目為主,既然是實(shí)戰(zhàn),就得考慮好需要準(zhǔn)備哪些東西,所有的準(zhǔn)備都做好了,才能正確的往下進(jìn)行。本章節(jié)目的在于把之前學(xué)習(xí)的知識(shí)點(diǎn)進(jìn)行一次串聯(lián),加深一下映像!
本次實(shí)戰(zhàn)準(zhǔn)備了三個(gè)案例:
- WordPress + MySQL
- Spring Boot項(xiàng)目
- Nacos服務(wù)注冊與發(fā)現(xiàn)
每個(gè)案例都會(huì)以不同的通信方式去部署。
1.1、服務(wù)搭建步驟
- 確定自己當(dāng)前的服務(wù)有哪些
- 服務(wù)是官方的還是自定義的
- 若是自定義則需要編寫Dockerfile
- 自定義的鏡像上傳鏡像倉庫 【可選】
- 服務(wù)隔離【可選】
- 服務(wù)很多的情況下,為了方便管理,一般會(huì)創(chuàng)建一個(gè)獨(dú)立的命名空間為這個(gè)項(xiàng)目使用
- 創(chuàng)建服務(wù)所需的 YAML 文件
- 服務(wù)發(fā)現(xiàn)的策略
- 通過 Service NodePort實(shí)現(xiàn)集群內(nèi)部通信
- 通過 Ingress 實(shí)現(xiàn)集群內(nèi)外通信
- 服務(wù)監(jiān)控、日志收集等 【暫不實(shí)現(xiàn)】
- 本章不演示,因?yàn)槟壳斑€沒有開始學(xué)習(xí)到這部分,等到后面再慢慢分享!
2、項(xiàng)目搭建
2.1、WordPress + MySQL
2.1.1 搭建說明
- 2個(gè)服務(wù)都使用官方 image,所以無需編寫Dockerfile
- 創(chuàng)建命名空間
- 編寫 YAML 文件
- mysql 服務(wù)我們只給wordpress訪問,所以直接用 ClusterIP方式實(shí)現(xiàn)集群內(nèi)通信即可。
- wordpress 服務(wù)需要外部訪問,使用NodePort方式進(jìn)行通信。
2.1.2 服務(wù)搭建
-
創(chuàng)建 WordPress 命名空間
[root@master-kubeadm-k8s wordpress]# kubectl create namespace wordpress namespace/wordpress created -
創(chuàng)建 wordpress-db.yaml 文件
apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deploy namespace: wordpress # 指定命名空間 labels: app: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: nodeSelector: name: ingress # 這里增加 節(jié)點(diǎn)選擇器 , 前面章節(jié)我們?yōu)?worker01 節(jié)點(diǎn)創(chuàng)建了 name: ingress 標(biāo)簽,這里用一下 containers: - name: mysql image: mysql:5.6 imagePullPolicy: IfNotPresent # 拉取策略,本地有則使用本地鏡像,不拉取 ports: - containerPort: 3306 name: dbport env: - name: MYSQL_ROOT_PASSWORD # 定義mysql root用戶密碼 value: root - name: MYSQL_DATABASE # 創(chuàng)建一個(gè)數(shù)據(jù)庫 名為 wordpress value: wordpress - name: MYSQL_USER # wordpress數(shù)據(jù)庫的用戶名 value: wordpress - name: MYSQL_PASSWORD # wordpress數(shù)據(jù)庫的密碼 value: wordpress volumeMounts: # 指定容器的映射目錄 - name: db mountPath: /var/lib/mysql volumes: # 指定宿主機(jī)的映射目錄 - name: db hostPath: path: /var/lib/mysql --- # 定義 Service 資源 apiVersion: v1 kind: Service metadata: name: mysql namespace: wordpress spec: type: NodePort selector: app: mysql ports: - name: mysqlport protocol: TCP port: 3306 targetPort: dbport -
創(chuàng)建 wordpress.yaml 文件
apiVersion: apps/v1 kind: Deployment metadata: name: wordpress-deploy namespace: wordpress labels: app: wordpress spec: selector: matchLabels: app: wordpress template: metadata: labels: app: wordpress spec: containers: - name: wordpress image: wordpress imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: wdport env: - name: WORDPRESS_DB_HOST # 指定數(shù)據(jù)庫ip:port value: 10.104.83.208:3306 # 這里用mysql的service的ip、名稱或pod的ip都可以 - name: WORDPRESS_DB_USER # 指定數(shù)據(jù)庫用戶名 value: wordpress - name: WORDPRESS_DB_PASSWORD # 指定數(shù)據(jù)庫密碼 value: wordpress --- apiVersion: v1 kind: Service metadata: name: wordpress namespace: wordpress spec: type: NodePort # 指定 Service 網(wǎng)絡(luò)模式 selector: app: wordpress ports: - name: wordpressport protocol: TCP port: 80 targetPort: wdport -
創(chuàng)建資源
# 創(chuàng)建 wordpress-db [root@master-kubeadm-k8s wordpress]# kubectl apply -f wordpress-db.yaml deployment.apps/mysql-deploy created service/mysql created # 創(chuàng)建 wordpress [root@master-kubeadm-k8s wordpress]# kubectl apply -f wordpress.yaml deployment.apps/wordpress-deploy created service/wordpress created # 查看 Pod [root@master-kubeadm-k8s wordpress]# kubectl get pods -n wordpress NAME READY STATUS RESTARTS AGE mysql-deploy-868f4cbd7b-chkw5 1/1 Running 0 4m10s wordpress-deploy-5c898774dc-8kckq 1/1 Running 0 2m55s # 查看 Service,得到 nodePort 32731 [root@master-kubeadm-k8s wordpress]# kubectl get svc -n wordpress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql ClusterIP 10.104.83.208 <none> 3306/TCP 3m14s wordpress NodePort 10.100.137.131 <none> 80:32731/TCP 2m56s -
測試
訪問宿主機(jī) ip:32731
image.png
若出現(xiàn)訪問不通的情況, 可以在宿主機(jī)執(zhí)行
iptables -P FORWARD ACCEPT命令就可以解決
2.2、Spring Boot 項(xiàng)目部署
2.2.1 搭建說明
- 準(zhǔn)備服務(wù),生成 Jar 文件并上傳服務(wù)器
- 服務(wù)是自己的項(xiàng)目代碼,需要編寫Dockerfile
- 鏡像上傳鏡像倉庫
- 編寫 YAML 文件
- 為了供外部訪問,采用 Ingress controller方式進(jìn)行通信
2.2.2 服務(wù)搭建
-
準(zhǔn)備服務(wù)
image.png
準(zhǔn)備 Jar 包并上傳至服務(wù)器
-
編寫Dockerfile并生成 image
FROM openjdk:8-jre-alpine COPY springboot-demo-0.0.1-SNAPSHOT.jar /springboot-demo.jar ENTRYPOINT ["java","-jar","/springboot-demo.jar"][root@master-kubeadm-k8s k8s-springboot-demo]# vi Dockerfile # 生成 springboot-demo-image [root@master-kubeadm-k8s k8s-springboot-demo]# docker build -t springboot-demo-image . Sending build context to Docker daemon 17.6MB Step 1/3 : FROM openjdk:8-jre-alpine 8-jre-alpine: Pulling from library/openjdk e7c96db7181b: Pull complete f910a506b6cb: Pull complete b6abafe80f63: Pull complete Digest: sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193 Status: Downloaded newer image for openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY springboot-demo-0.0.1-SNAPSHOT.jar /springboot-demo.jar ---> 40cbd786e301 Step 3/3 : ENTRYPOINT ["java","-jar","/springboot-demo.jar"] ---> Running in 79f29aff270c Removing intermediate container 79f29aff270c ---> 845f0d0b2d7f Successfully built 845f0d0b2d7f Successfully tagged springboot-demo-image:latest -
上傳至阿里云鏡像倉庫
# 1、登錄阿里云鏡像倉庫 [root@master-kubeadm-k8s k8s-springboot-demo]# sudo docker login --username=【用戶名】 registry.cn-hangzhou.aliyuncs.com Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded # 2、打 tag docker tag springboot-demo-image registry.cn-hangzhou.aliyuncs.com/【命名空間】/springboot-demo-image:v1.0 # 3、上傳鏡像 [root@master-kubeadm-k8s k8s-springboot-demo]# docker push registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image] 2b85a76d2ba6: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:d9cd5f2ebd86c3e0c01064156c508c9ea557a8e8df0ae2f79be190844bb4b980 size: 1159image.png
-
編寫 YAML 文件
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-demo spec: selector: matchLabels: app: springboot-demo replicas: 1 template: metadata: labels: app: springboot-demo spec: containers: - name: springboot-demo # 這里就使用我們上傳的鏡像倉庫的image image: registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 ports: - containerPort: 8080 --- # 創(chuàng)建Pod的Service apiVersion: v1 kind: Service metadata: name: springboot-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-demo --- # 創(chuàng)建Ingress,定義訪問規(guī)則,一定要記得提前創(chuàng)建好nginx ingress controller apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: springboot-demo spec: rules: - host: tomcat.sunny.com # windows hosts中配置了與宿主機(jī)ip對(duì)應(yīng)的域名 http: paths: - path: / backend: serviceName: springboot-demo servicePort: 80因?yàn)樵谥暗恼鹿?jié)演示中,我們已經(jīng)創(chuàng)建好了 Ingress Controller,所以這里直接寫 Ingress規(guī)則即可
-
創(chuàng)建資源
# 創(chuàng)建資源 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl apply -f springboot-demo.yaml deployment.apps/springboot-demo created service/springboot-demo created ingress.networking.k8s.io/springboot-demo created # 查看 Pod, 發(fā)現(xiàn)還沒創(chuàng)建好 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get pods NAME READY STATUS RESTARTS AGE springboot-demo-5f6f5c9696-66vvm 0/1 ContainerCreating 0 8s # 看下 Pod 描述, 看當(dāng)前在做什么 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl describe pod springboot-demo-5f6f5c9696-5gj9k # ...省略... # ===================== 發(fā)現(xiàn)拉取鏡像失敗了 ====================== Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 57s default-scheduler Successfully assigned default/springboot-demo-5f6f5c9696-5gj9k to worker01-kubeadm-k8s Normal Pulling 55s kubelet, worker01-kubeadm-k8s Pulling image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0" Warning Failed 5s kubelet, worker01-kubeadm-k8s Failed to pull image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0": rpc error: code = Unknown desc = Error response from daemon: pull access denied for registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image, repository does not exist or may require 'docker login' Warning Failed 5s kubelet, worker01-kubeadm-k8s Error: ErrImagePull Normal BackOff 4s kubelet, worker01-kubeadm-k8s Back-off pulling image "registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0" Warning Failed 4s kubelet, worker01-kubeadm-k8s Error: ImagePullBackOff其實(shí)這是權(quán)限問題,K8S需要有一個(gè)認(rèn)證才能從私有倉庫拉取鏡像,可以創(chuàng)建 Secret 解決
如果是公開庫就可以正常拉取,不會(huì)出現(xiàn)這種問題
-
解決K8S拉取不了私有鏡像倉庫的問題
官方文檔:從私有倉庫拉取鏡像
創(chuàng)建 Secret
# 在集群中創(chuàng)建保存授權(quán)令牌的 Secret [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl create secret docker-registry [自定義secret名稱] --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=[用戶名] --docker-password=[密碼] --docker-email=[郵箱] secret/registry-aliyun created # 檢查 Secret [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get secret registry-aliyun --output=yaml apiVersion: v1 data: .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5jbi1oYW5nemhvdS5hbGl5dW5jcy5jb20iOnsidXNlcm5hbWUiOiJ5enlfemhhb3lhbmdAMTYzLmNvbSIsInBdkjhasjdhksabdkajaksddasdaWwiOiJ5enlfemhhb3lhbmdAMTYzLmNvbSIsImF1dGgiOiJlWHAkcjnhkcnhamoewr3242309jdsjaldj092qeGIxbEJUa2MxTmpJMU5ERTQifX19 kind: Secret metadata: creationTimestamp: "2020-04-03T16:50:24Z" name: registry-aliyun namespace: default resourceVersion: "109789" selfLink: /api/v1/namespaces/default/secrets/registry-aliyun uid: 368a54cd-22ggb-11ea-28ty-5254008afee6 type: kubernetes.io/dockerconfigjson-
修改 YAML 文件,增加 Secret認(rèn)證
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-demo spec: selector: matchLabels: app: springboot-demo replicas: 1 template: metadata: labels: app: springboot-demo spec: containers: - name: springboot-demo # 這里就使用我們上傳的鏡像倉庫的image image: registry.cn-hangzhou.aliyuncs.com/sunny95/springboot-demo-image:v1.0 ports: - containerPort: 8080 #=========增加 Secret=========== imagePullSecrets: - name: registry-aliyun # 注意名稱要與創(chuàng)建時(shí)指定的名稱一致 #=========增加 Secret=========== --- # 創(chuàng)建Pod的Service apiVersion: v1 kind: Service metadata: name: springboot-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-demo --- # 創(chuàng)建Ingress,定義訪問規(guī)則,一定要記得提前創(chuàng)建好nginx ingress controller apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: springboot-demo spec: rules: - host: tomcat.sunny.com # windows hosts中配置了與宿主機(jī)ip對(duì)應(yīng)的域名 http: paths: - path: / backend: serviceName: springboot-demo servicePort: 80
-
重新創(chuàng)建資源
# 創(chuàng)建資源 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl apply -f springboot-demo.yaml deployment.apps/springboot-demo created service/springboot-demo created ingress.networking.k8s.io/springboot-demo created # 已經(jīng)創(chuàng)建完成 [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get pods NAME READY STATUS RESTARTS AGE springboot-demo-75f846fd48-zpwtw 1/1 Running 0 2m2s
-
-
查看資源
# 查看 Service [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d springboot-demo ClusterIP 10.109.134.133 <none> 80/TCP 4m27s # 查看 ingress [root@master-kubeadm-k8s k8s-springboot-demo]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE springboot-demo tomcat.sunny.com 80 4m40s -
測試
image.png
測試成功訪問到 SpringBoot 服務(wù)
2.3、Nacos 服務(wù)注冊與發(fā)行
2.3.1 搭建說明
- 準(zhǔn)備Nacos注冊中心
- 準(zhǔn)備兩個(gè)服務(wù),一個(gè)服務(wù)依賴另一個(gè)服務(wù)
- user、order服務(wù)
- 服務(wù)注冊至 Nacos
- 編寫兩個(gè)服務(wù)的Dockerfile
- 編寫 YAML 文件
- Nacos注冊中心這里不通過容器部署,所以就不寫 YAML 文件了
2.3.2 服務(wù)搭建
-
準(zhǔn)備 Nacos 注冊中心
注冊中心的選擇是自定義的,這里只是選擇了Nacos作為演示,你也可以選擇其他的注冊中心去測試!
以單機(jī)模式啟動(dòng) nacos
image.png
訪問物理機(jī) ip:8848/nacos 即可訪問注冊中心
nacos 默認(rèn)的用戶名:nacos,密碼:nacos

- 準(zhǔn)備user、order項(xiàng)目并驗(yàn)證
-
POM 依賴
注意:Cloud生態(tài)對(duì)版本依賴還是挺大的,如果SpringBoot版本與SpringCloud版本不匹配可能會(huì)出現(xiàn)問題的
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入nacos client依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!--加入Spring Cloud依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <!--加入Spring Cloud Alibaba依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>0.9.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> -
user 服務(wù)
-
配置文件
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.55.33.23:8848 application: name: user server: port: 8080 -
controller
@RestController @RequestMapping("/user") public class TestController { @Autowired private DiscoveryClient discoveryClient; /** * 通過Cloud提供的 DiscoveryClient 來發(fā)現(xiàn)服務(wù) */ @RequestMapping("/test") public Map<String, Object> findServiceInstance() throws Exception{ //查詢指定服務(wù)名稱下的所有實(shí)例的信息 List<ServiceInstance> list=this.discoveryClient.getInstances("order"); ServiceInstance serviceInstance=list.get(0); URI uri = serviceInstance.getUri(); String testResult = this.testUrl(uri.toString()); Map<String, Object> map = new HashMap<>(); map.put("service", list); map.put("uri", uri.toString()); //保存 能否 ping 通 order 服務(wù)的結(jié)果 map.put("testResult", testResult); return map; } /** * 測試user服務(wù)能否 ping 通order服務(wù)的ip * * @param urlString order服務(wù)所在機(jī)器的ip */ public String testUrl(String urlString){ URL url; try { url = new URL(urlString); URLConnection co = url.openConnection(); co.connect(); return "連接可用"; } catch (Exception e1) { return "連接打不開!"; } } }
-
-
order 服務(wù)
order我們不提供服務(wù)接口,我們只通過user服務(wù)來訪問order服務(wù)所在機(jī)器的ip判斷是否可以連通。
-
配置文件
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.55.33.23:8848 application: name: order server: port: 9090
-
-
啟動(dòng)服務(wù)后即可注冊到Nacos
image.png
-
+ user服務(wù)地址

+ order 服務(wù)地址

-
本地測試服務(wù)
訪問 user 服務(wù),可以正常獲取到 order 服務(wù)的地址信息
image.png
-
編寫 2 個(gè)項(xiàng)目的 Dockerfile
-
user 服務(wù)
FROM openjdk:8-jre-alpine COPY user-0.0.1-SNAPSHOT.jar /user.jar ENTRYPOINT ["java","-jar","/user.jar"] -
order 服務(wù)
FROM openjdk:8-jre-alpine COPY order-0.0.1-SNAPSHOT.jar /order.jar ENTRYPOINT ["java","-jar","/order.jar"]
-
-
獲取 2 個(gè)項(xiàng)目的 Jar 包與Dockerfile一起上傳服務(wù)器
[root@master-kubeadm-k8s nacos]# ll total 0 drwxr-xr-x. 2 root root 56 Apr 4 06:05 order drwxr-xr-x. 2 root root 55 Apr 4 06:05 user # order 服務(wù) [root@master-kubeadm-k8s nacos]# ll ./order/ total 32552 -rw-r--r--. 1 root root 107 Apr 4 06:05 Dockerfile -rw-r--r--. 1 root root 33328956 Apr 4 06:04 order-0.0.1-SNAPSHOT.jar # user 服務(wù) [root@master-kubeadm-k8s nacos]# ll ./user/ total 32556 -rw-r--r--. 1 root root 104 Apr 4 06:05 Dockerfile -rw-r--r--. 1 root root 33330518 Apr 4 06:04 user-0.0.1-SNAPSHOT.jar -
生成 image 鏡像
# 生成 user-image [root@master-kubeadm-k8s user]# docker build -t user-image . Sending build context to Docker daemon 33.33MB Step 1/3 : FROM openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY user-0.0.1-SNAPSHOT.jar /user.jar ---> cdcf57ffcd9e Step 3/3 : ENTRYPOINT ["java","-jar","/user.jar"] ---> Running in fcebef970173 Removing intermediate container fcebef970173 ---> c791a8564979 Successfully built c791a8564979 Successfully tagged user-image:latest # 生成 order-image [root@master-kubeadm-k8s order]# docker build -t order-image . Sending build context to Docker daemon 33.33MB Step 1/3 : FROM openjdk:8-jre-alpine ---> f7a292bbb70c Step 2/3 : COPY order-0.0.1-SNAPSHOT.jar /order.jar ---> 60d8a5f1f8d1 Step 3/3 : ENTRYPOINT ["java","-jar","/order.jar"] ---> Running in ca058de2b8a0 Removing intermediate container ca058de2b8a0 ---> e27b4f1bfce9 Successfully built e27b4f1bfce9 Successfully tagged order-image:latest -
上傳 image 到鏡像倉庫
一般K8S要使用鏡像都需要上傳到鏡像倉庫,讓它從網(wǎng)上去下載鏡像,因?yàn)镵8S在創(chuàng)建Pod不是只在固定的節(jié)點(diǎn)創(chuàng)建的,它會(huì)分配到不同的節(jié)點(diǎn)上。
如果不想將 image 上傳鏡像倉庫,那只能在所有節(jié)點(diǎn)中都創(chuàng)建出 image才行
# 為 user-image 打 tag [root@master-kubeadm-k8s user]# docker tag user-image registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 # 上傳 user-image 到鏡像倉庫 [root@master-kubeadm-k8s user]# docker push registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image] bc5590316af2: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:837894b2657b7084bdc64ggfddf347afc27ae1a8dfg324bdd238aa108c3464 size: 1159 # 為 order-image 打 tag [root@master-kubeadm-k8s user]# docker tag order-image registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 [root@master-kubeadm-k8s ~]# docker push registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image] 0b5a4e8a7fda: Pushed edd61588d126: Pushed 9b9b7f3d56a0: Pushed f1b5933fe4b5: Pushed v1.0: digest: sha256:896088772c5f1c187db2645e29fsdghdfg4328c8c94dd783ddfg32ab7618d50 size: 1159 -
編寫 YAML 文件
-
user 服務(wù)
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: user spec: selector: matchLabels: app: user replicas: 1 template: metadata: labels: app: user spec: containers: - name: user image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/user-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 8080 --- # 創(chuàng)建Pod的Service apiVersion: v1 kind: Service metadata: name: user spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: user --- # 創(chuàng)建Ingress,定義訪問規(guī)則 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: user spec: rules: - host: tomcat.sunny.com http: paths: - path: / backend: serviceName: user servicePort: 80 -
order 服務(wù)
order 服務(wù)無需對(duì)外開放,所以不需要編寫 Ingress 規(guī)則
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: order spec: selector: matchLabels: app: order replicas: 1 template: metadata: labels: app: order spec: containers: - name: order image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9090 --- # 創(chuàng)建Pod的Service apiVersion: v1 kind: Service metadata: name: order spec: ports: - port: 80 protocol: TCP targetPort: 9090 selector: app: order
-
-
創(chuàng)建資源
# 創(chuàng)建 user 資源 [root@master-kubeadm-k8s user]# kubectl apply -f nacos-user.yaml deployment.apps/user created service/user created ingress.networking.k8s.io/user created # 創(chuàng)建 order 資源 [root@master-kubeadm-k8s order]# kubectl apply -f nacos-order.yaml deployment.apps/order created service/order created -
查看資源
# 服務(wù)都正常運(yùn)行了 [root@master-kubeadm-k8s order]# kubectl get pods NAME READY STATUS RESTARTS AGE order-d5f8d8b44-2p4m4 1/1 Running 0 4m30s user-54b8fccd67-9925h 1/1 Running 0 7m2s # 查看 Ingress [root@master-kubeadm-k8s order]# kubectl get ingress NAME HOSTS ADDRESS PORTS AGE user tomcat.sunny.com 80 7m52s -
查看Nacos注冊中心
服務(wù)正常注冊
image.png
-
驗(yàn)證訪問
測試成功
image.png
2.3.3 服務(wù)注冊可能存在的坑
現(xiàn)在的情況是 user 與 order 服務(wù)都部署在集群內(nèi),通信是肯定沒問題的。
如果 user 服務(wù)是運(yùn)行在外部的,以現(xiàn)在的配置,user 服務(wù)肯定是無法訪問到 集群內(nèi)的 order 服務(wù)的,因?yàn)樗麄冏缘?Nacos 的 IP 不是在同一個(gè)網(wǎng)段的,所以肯定無法連通!
-
user
image.png
-
order
image.png
-
測試
image.png
-
解決辦法
因?yàn)?order 服務(wù)注冊到 Nacos 的IP是用于集群內(nèi)通信的,那我們只要想辦法把這個(gè)IP換掉,換成外部服務(wù)可以 ping 通的 IP 不就可以了?
以我們現(xiàn)在學(xué)習(xí)過的網(wǎng)絡(luò)知識(shí),我們知道外部服務(wù)要訪問集群內(nèi)的服務(wù),目前有兩種方式:
- NodePort
- HostPort
由于NodePort會(huì)在集群內(nèi)所有節(jié)點(diǎn)都開放一個(gè)端口,所以我們不推薦使用。
而 HostPort 僅僅是在Pod所在節(jié)點(diǎn)開放端口,其實(shí) HostPort 就是 Docker 中的 Host 網(wǎng)絡(luò)模式,它是共享宿主機(jī)的 IP 與 端口的。這種方式也是現(xiàn)在比較推薦的做法!
使用HostPort網(wǎng)絡(luò)模式的情況下,如果服務(wù)高可用會(huì)有端口沖突問題
可以使用 Pod 的調(diào)度策略,盡可能在高可用的情況下,不將pod分配到同一個(gè)Worker Node中
-
修改 order 服務(wù)的 YAML 文件
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: order spec: selector: matchLabels: app: order replicas: 1 template: metadata: labels: app: order spec: # ============修改為HostPort模式============= hostNetwork: true # ============修改為HostPort模式============= containers: - name: order image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/order-image:v1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 9090 --- # 創(chuàng)建Pod的Service apiVersion: v1 kind: Service metadata: name: order spec: ports: - port: 80 protocol: TCP targetPort: 9090 selector: app: order 重新創(chuàng)建資源并查看 Nacos 中 order 服務(wù)的地址信息

結(jié)果發(fā)現(xiàn)這并不是我想要的IP,我們檢查一下這個(gè)容器使用的網(wǎng)卡信息。

從這里發(fā)現(xiàn)原因,它是把 eth0 網(wǎng)卡的IP注冊上去了,這個(gè)IP是沒法通過外部來訪問的,我們要修改讓它使用 eth1 網(wǎng)卡才行。
-
Nacos解決方案
-
通過查看文檔,可以選擇配置不同的網(wǎng)卡或者IP
(參考o(jì)rg.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties的配置)
-
選擇固定網(wǎng)卡配置項(xiàng)
-
在 order 項(xiàng)目的配置文件中增加配置
spring: cloud: nacos: discovery: #指定nacos server的地址 server-addr: 101.111.45.23:8848 # 指定網(wǎng)卡配置項(xiàng) network-interface: eth1 application: name: order server: port: 9090
-
重新生成 Jar、image,重新創(chuàng)建資源
-
查看Nacos中 order 服務(wù)的地址信息
image.png
-
現(xiàn)在這個(gè)IP是我們想要的了
-
測試
image.png













