k8s springcloud apollo

springcloud + apollo的微服务化部署

创建namespace

建立属于微服务体系下的namespace,cloud.yml

apiVersion: v1
kind: Namespace
metadata:
  name: springcloud

执行 kubectl apply -f cloud.yml

eureka

由于eureka是有状态的服务,因此采用statefulset部署

  1. 首先创建镜像,编写DOCKFILE
FROM java:8
copy ./www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/iggreport-registry-2.1.5.RELEASE.jar ${APP_OPT}

执行docker build -t eureka:v1 .

  1. 创建eureka.yml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: springcloud
type: Opaque
data:
  password: WDhHbkdYcVdGUlg5V3Z3ZQ== 

---
apiVersion: v1
kind: Service
metadata:
  name: eureka
  namespace: springcloud
  labels:
    app: eureka
spec:
  clusterIP: None
  ports:
    - port: 8761
      targetPort: 8761
  selector:
    app: eureka

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka-set
  namespace: springcloud
spec:
  serviceName: eureka
  replicas: 2
  selector:
    matchLabels:
      app: eureka
  template:
    metadata:
      labels:
        app: eureka
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: eureka
          image: eureka:v4
          ports:
          - containerPort: 8761
          env:
            - name: APP_NAME
              value: "eureka"
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: SPRING_APPLICATION_NAME
              value: "igg-report-registry" 
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: password
            - name: APP_OPT
              value: "
                     --eureka.instance.hostname=${POD_NAME}.${APP_NAME}
                     --registerWithEureka=true
                     --fetchRegistry=true
                     --eureka.instance.preferIpAddress=false
                     --eureka.client.serviceUrl.defaultZone=http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-0.${APP_NAME}:8761/eureka/,http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-1.${APP_NAME}:8761/eureka/
                     "

由于我的注册中心有做安全校验,因此配置注册中心的时候需要填写密码,而密码不想明文写入到配置的话需要自己加密下,加密方法如下:

[root@master eureka]# echo -n 'X8GnGXqWFRX9Wvwe' | base64
WDhHbkdYcVdGUlg5V3Z3ZQ==

"WDhHbkdYcVdGUlg5V3Z3ZQ=="这个就是经过base64加密后的密码了。
StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序。
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)
    从上面的应用场景可以发现,StatefulSet由以下几个部分组成:
  • 用于定义网络标志(DNS domain)的Headless Service
  • 用于创建PersistentVolumes的volumeClaimTemplates
  • 定义具体应用的StatefulSet
    StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中
  • serviceName为Headless Service的名字
  • 0..N-1为Pod所在的序号,从0开始到N-1
  • statefulSetName为StatefulSet的名字
  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
  • .cluster.local为Cluster Domain

apollo配置中心

由于apollo配置中心需要mysql数据库的支持,而mysql不是部署在k8s集群内,因此需要建立一个service可以代理到外部服务去
endpoints.yml

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: springcloud
spec:
  clusterIP: 192.168.186.163
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

---
kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
  namespace: springcloud
subsets:
  - addresses:
      - ip: 10.0.3.166
    ports:
      - port: 3306

这样通过访问这个serviceIp的3306就能访问到外部节点的mysql

apollo-config部署

先自建apollo-config的镜像

FROM java:8
COPY www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/apollo-configservice-1.5.1.jar ${APP_OPT}

apollo-config.yml

apiVersion: v1
kind: Secret
metadata:
  name: apollo-config
  namespace: springcloud
type: Opaque
data:
  password: QXF1YXl3RGJDYVNoeEczbA== 

---
apiVersion: v1
kind: Service
metadata:
  name: apollo-config
  namespace: springcloud
  labels:
    app: apollo-config
spec:
  ports:
    - port: 8888
      targetPort: 8888
  selector:
    app: apollo-config

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apollo-config
  namespace: springcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apollo-config
  template:
    metadata:
      labels:
        app: apollo-config
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: apollo-config
          image: apollo-config:v4
          ports:
          - containerPort: 8888
          env:
            - name: SPRING_APPLICATION_NAME
              value: "apollo-configservice" 
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: apollo-config
                  key: password
            - name: APP_OPT
              value: "
                     --eureka.instance.hostname=apollo-config
                     --registerWithEureka=true
                     --fetchRegistry=true
                     --eureka.instance.preferIpAddress=false
                     --spring.datasource.url=jdbc:mysql://my-service:3306/apollo_config?useSSL=false&characterEncoding=utf-8
                     --eureka.client.serviceUrl.defaultZone=http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-0:8761/eureka/,http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-1:8761/eureka/
                     "

apollo-admin部署

自建apollo-admin镜像

FROM java:8
copy ./www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/apollo-adminservice-1.5.1.jar ${APP_OPT}

apollo-admin.yml

apiVersion: v1
kind: Secret
metadata:
  name: apollo-admin
  namespace: springcloud
type: Opaque
data:
  password: QXF1YXl3RGJDYVNoeEczbA== 

---
apiVersion: v1
kind: Service
metadata:
  name: apollo-admin
  namespace: springcloud
  labels:
    app: apollo-admin
spec:
  ports:
    - port: 8070
      targetPort: 8070
  selector:
    app: apollo-admin

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apollo-admin
  namespace: springcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apollo-admin
  template:
    metadata:
      labels:
        app: apollo-admin
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: apollo-admin
          image: apollo-admin:v1
          ports:
          - containerPort: 8070
          env:
            - name: APP_NAME
              value: apollo-admin
            - name: SPRING_APPLICATION_NAME
              value: "apollo-adminservice" 
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: apollo-admin
                  key: password
            - name: APP_OPT
              value: "
                     --eureka.instance.hostname=${APP_NAME}
                     --registerWithEureka=true
                     --fetchRegistry=true
                     --spring.datasource.url=jdbc:mysql://my-service:3306/apollo_config?useSSL=false&characterEncoding=utf-8
                     --eureka.instance.preferIpAddress=false
                     --eureka.client.serviceUrl.defaultZone=http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-0.${APP_NAME}:8761/eureka/,http://${SPRING_APPLICATION_NAME}:${PASSWORD}@eureka-set-1.${APP_NAME}:8761/eureka/
                     "

apollo-portal部署

自建apollo-portal镜像

FROM java:8
copy ./www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/apollo-portal-1.5.1.jar

apollo-portal.yml

apiVersion: v1
kind: Service
metadata:
  name: apollo-portal
  namespace: springcloud
  labels:
    app: apollo-portal
spec:
  ports:
    - port: 8060
      targetPort: 8060
  selector:
    app: apollo-portal

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apollo-portal
  namespace: springcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apollo-portal
  template:
    metadata:
      labels:
        app: apollo-portal
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: apollo-portal
          image: apollo-portal:v1
          ports:
          - containerPort: 8060

由于apollo-portal需要web页面对外访问,因此需要使用ingress配合service,将其对外访问

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  namespace: springcloud
spec:
  rules:
    #定义域名
    - host: apollo.ingress.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: apollo-portal
              port:
                number: 8060

api-common部署

api-common有使用到apollo的配置中心
所以配置文件如下:

app:
  id: iggreport-api-common
apollo:
  meta: http://apollo-config:8888
  bootstrap:
    enabled: true
    namespaces: application,application.yml

构建镜像Dockerfile

FROM java:8
copy ./www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/iggreport-api-common-2.1.4.RELEASE.jar ${APP_OPT}

api.yml

apiVersion: v1
kind: Service
metadata:
  name: api-common-service
  namespace: springcloud
  labels:
    app: api-common-service
spec:
  ports:
    - port: 8090
      targetPort: 8090
  selector:
    app: api-common
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-common
  namespace: springcloud
spec:
  replicas: 2
  selector:
    matchLabels:
      app: api-common
  template:
    metadata:
      labels:
        app: api-common
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: api-common
          image: api:v1
          ports:
          - containerPort: 8090
          env:
            - name: APP_NAME
              value: api-common-service
            - name: APP_OPT
              value: "
                     --eureka.instance.hostname=${APP_NAME}  #这里记得要用service的名字,否则网关使用此hostname无法访问
                     "

gateway部署

由于网关需要redis,因此也需要建个service代理到外部服务的redis集群
endpoint.yml

kind: Service
apiVersion: v1
metadata:
  name: redis-service
  namespace: springcloud
spec:
  ports:
    - protocol: TCP
      port: 7000
      targetPort: 7000

---
kind: Endpoints
apiVersion: v1
metadata:
  name: redis-service
  namespace: springcloud
subsets:
  - addresses:
      - ip: 10.0.3.163
      - ip: 10.0.3.164
      - ip: 10.0.3.165
    ports:
      - port: 7000

自建镜像

FROM java:8
copy ./www /data/www
entrypoint java ${JVM:=-Xms1024m -Xmx1024m} -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF8 -jar /data/www/iggreport-gateway-2.2.0.RELEASE.jar ${APP_OPT}

gateway.yml

apiVersion: v1
kind: Service
metadata:
  name: gateway-service
  namespace: springcloud
  labels:
    app: gateway-service
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: gateway
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
  namespace: springcloud
spec:
  replicas: 2
  selector:
    matchLabels:
      app: gateway
  template:
    metadata:
      labels:
        app: gateway
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: gateway
          image: gateway:v1
          ports:
          - containerPort: 8080

然后由于gateway需要对外,因此也需要加入到ingress管理

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  namespace: springcloud
spec:
  rules:
    #定义域名
    - host: gateway.ingress.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: gateway-service
              port:
                number: 8080

这样一个完整的springcloud + apollo的统一配置中心就基于k8s搭建完毕

[root@master k8s]# kubectl get po -o wide -n springcloud
NAME                             READY   STATUS    RESTARTS   AGE    IP           NODE   NOMINATED NODE   READINESS GATES
api-common-5c59b9b649-4rkrm      1/1     Running   0          116m   10.10.2.93   cdh2   <none>           <none>
api-common-5c59b9b649-swpq8      1/1     Running   0          116m   10.10.1.88   cdh3   <none>           <none>
apollo-admin-6dfcf44f8b-flwtc    1/1     Running   0          25h    10.10.2.83   cdh2   <none>           <none>
apollo-config-5d7bddf55c-cn4ph   1/1     Running   0          24h    10.10.2.90   cdh2   <none>           <none>
apollo-portal-bb7d4685d-srw2r    1/1     Running   0          24h    10.10.2.92   cdh2   <none>           <none>
eureka-set-0                     1/1     Running   0          24h    10.10.2.91   cdh2   <none>           <none>
eureka-set-1                     1/1     Running   0          24h    10.10.1.87   cdh3   <none>           <none>
gateway-949d4f958-4ft8x          1/1     Running   0          9m7s   10.10.1.89   cdh3   <none>           <none>
gateway-949d4f958-b4wc7          1/1     Running   0          9m7s   10.10.2.94   cdh2   <none>           <none>

[root@master k8s]# kubectl get svc -o wide -n springcloud
NAME                 TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)    AGE     SELECTOR
api-common-service   ClusterIP   192.168.144.76    <none>        8090/TCP   116m    app=api-common
apollo-admin         ClusterIP   192.168.118.145   <none>        8070/TCP   25h     app=apollo-admin
apollo-config        ClusterIP   192.168.134.51    <none>        8888/TCP   5d23h   app=apollo-config
apollo-portal        ClusterIP   192.168.31.38     <none>        8060/TCP   25h     app=apollo-portal
eureka               ClusterIP   None              <none>        8761/TCP   3d23h   app=eureka
gateway-service      ClusterIP   192.168.230.235   <none>        8080/TCP   9m27s   app=gateway
my-service           ClusterIP   192.168.186.163   <none>        3306/TCP   5h10m   <none>
redis-service        ClusterIP   192.168.143.180   <none>        7000/TCP   75m     <none>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容