Origin

apollo k8s 完整搭建记录

在把apollo转到k8s的时候,遇到了一些麻烦,所以记录下来,为大家提供一个参考。本文档没有提供关于docker的一些基础操作。大家如果不清楚操作,可以看一下这个k8s 部署文档

部署 mysql

我在创建mysql容器的时候,是非常顺利的。把镜像放在harbor私服上,然后创建yaml文件

apiVersion: apps/v1
kind: Deployment #指定这是一个deployment
metadata:
  name: mysql-deploy #这里是deployment的名称
  namespace: public-c  # 这里是deployment所在的namespace
spec:
  replicas: 1 #需要启动几个副本
  selector:
    matchLabels:
      app: mysql #需要管理的pod的名称
  template: #模板
    metadata:
      labels:
        app: mysql #pod名称
    spec:
      containers:
      - name: mysql #pod名称  
        env:
        - name: MYSQL_ROOT_PASSWORD #设置MYSQL的root密码
          value: "abcdefg"     #root密码
        image: harbortest.picchealth.com/lion_test/mysql:5.7 #容器的镜像路径
        ports:
        - containerPort: 3306 #端口
          name: httpport
        resources:
          limits:
            cpu: 2000m #每一个pod的限制
            memory: 512Mi #每一个pod的限制
          requests:
            cpu: 100m #初始值
            memory: 256Mi #初始值
        volumeMounts: #数据存放路径
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      # 宿主机上的目录 挂载的位置
      - name: mysql-persistent-storage
        nfs:
          path: /NFS/PUBLIC
          server: xxx.xxx.xxx.xxx


        

---
#创建service
apiVersion: v1 
kind: Service
metadata:
  name: mysql-svc #service name
  namespace: public-c #service所在的命名空间
  labels:
    app: mysql-svc 
spec:
  selector:
    app: mysql #service所管理哪个 pod
  type: NodePort
  ports:
  - name: http
    port: 3306 #端口 
    targetPort: 3306 #pod的端口
    protocol: TCP
    nodePort: 30006

在上面的文件里,有几个注意的地方:

  • nfs挂载,这个的目的是假如我的这个容器由于某种原因死掉了,k8s在其他的node节点上自动拉起来的时候,访问的同一个存储。mountPath 是把容器内的这个目录,挂载到 nfs.server的nfs.path下

      volumeMounts: #数据存放路径
              - name: mysql-persistent-storage
                mountPath: /var/lib/mysql
            volumes:
            # 宿主机上的目录 挂载的位置
            - name: mysql-persistent-storage
              nfs:
                path: /NFS/PUBLIC
                server: xxx.xxx.xxx.xxx
    
  • 没有配置ingress。 是因为我不需要绑定dns从而让外网访问。我只需要让内网和pod可以与其通讯就可以了
  • 配置 service的type为NodePort,我们可以看到几个端口,其中port是容器启动端口,targetPort为pod的通讯端口,nodePort则是可以通过ip+nodePort 进行请求的端口.输入任意master ip,然后加上这个端口,就可以请求到这个pod的service上。 比如我在内网的环境,使用这个创建好的mysql,连接字符串就是:

    10.252.68.90:30006
    
      spec:
        selector:
          app: mysql #service所管理哪个 pod
        type: NodePort
        ports:
        - name: http
          port: 3306 #端口 
          targetPort: 3306 #pod的端口
          protocol: TCP
          nodePort: 30006
    
  • 创建mysql容器的时候,一定要配置一个初始密码

      containers:
            - name: mysql #pod名称  
              env:
              - name: MYSQL_ROOT_PASSWORD #设置MYSQL的root密码
                value: "abcdefg"     #root密码
    

启动mysql

  • 启动命令

      # kubectl apply -f mysql.yaml --kubeconfig ../kubeconfig/lion.kubeconfig
    
  • 查看结果

      # kubectl --kubeconfig ../kubeconfig/lion.kubeconfig get -n public-c deploy/mysql-deploy
      NAME           READY   UP-TO-DATE   AVAILABLE   AGE
      mysql-deploy   1/1     1            1           7d22h
    

    如果没有启动则是这样的

      # kubectl --kubeconfig ../kubeconfig/lion.kubeconfig get -n public-c deploy/mysql-deploy
      NAME           READY   UP-TO-DATE   AVAILABLE   AGE
      mysql-deploy   0/1     1            0           7d22h
    
  • 如果没有启动,查看命令

      # kubectl --kubeconfig ../kubeconfig/lion.kubeconfig get -n public-c deploy/mysql-deploy -o yaml
    
  • 查看日志

      kubectl --kubeconfig ../kubeconfig/lion.kubeconfig logs -n public-c deploy/mysql-deploy
    

    关于查看Pod的信息,还有一个命令

      kubectl --kubeconfig ../kubeconfig/lion.kubeconfig describe pod mysql-deploy -n public-c
    

部署apollo-config-service

初始化数据库

部署完mysql之后,我们将apollo的configDB和portalDB初始化进去

打包镜像

可以参考这篇文章docker部署apollo 或者也可以使用我已经打包的,我已经把images放到了内部的harbor上

apollo-config:harbortest.picchealth.com/lion_test/apollo-configservice:1.5.0
apollo-admin:harbortest.picchealth.com/lion_test/apollo-adminservice:1.5.0
apollo-portal:harbortest.picchealth.com/lion_test/apollo-portal:1.5.1

编写configmap

那么部署过apollo的同学都知道,我们启动apollo之前,需要先修改他的配置文件。把mysql的位置、env还有apollo的eureka配置好,那么我们用容器该怎么办呢?就是编写configmap 先看一下我配置的configmap

apiVersion: v1
kind: ConfigMap #类型是configmap
metadata:
  name: apollo-config-configmap #configMap的名称
  namespace: public-c #所属的命名空间
  labels:
    app: apollo-config-configmap 
#实际内容
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://mysql-svc.public-c:3306/ApolloConfigDB?characterEncoding=utf8
    spring.datasource.username = lion
    spring.datasource.password = abcdefg

application-github.properties: ,就是创建一个叫application-github.properties的文件, 后面就是文件的内容。多个文件的话 再从下面换行继续写,比如apollo-portal的configmap是这样写的
apiVersion: v1
kind: ConfigMap #类型是configmap
metadata:
  name: apollo-portal-configmap #configMap的名称
  namespace: public-c #所属的命名空间
  labels:
    app: apollo-portal-configmap 
#实际内容
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://mysql-svc.public-c:3306/ApolloPortalDB?characterEncoding=utf8
    spring.datasource.username = lion
    spring.datasource.password = abcdefg
  
  apollo-env.properties: |
    local.meta=
    dev.meta=
    fat.meta=http://apollo-config-svc.public-c:8080
    uat.meta=
    lpt.meta=
    pro.meta=

我们看到里面有个域名 叫 mysql-svc.public-c和apollo-config-svc.public-c,这个是什么呢? 这个是内部pod与pod通讯,可以通过内部域名的方式进行通讯。那么咱们内部的域名的规则是

SERVICE_NAME.SPACE_NAME

service_name 指的就是我们配置文件中,service的name,space_name指的是命名空间的name。这个端口,就是service的端口, 这是运维在创建K8s的CoreDNS组件的时候创建的。所以拿我们上面Mysql的为例,就是mysql-svc.public-c 注意,这个端口一定不是nodePort,而是service的port 我们可以通过命令看到这个端口

# kubectl --kubeconfig ../kubeconfig/lion.kubeconfig get -n public-c service/mysql-svc
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
mysql-svc   NodePort   10.106.43.120   <none>        3306:30006/TCP   7d23h

接下来就是将config map 应用上

# kubectl apply -f apolloconfig-confgmap.yaml --kubeconfig ../kubeconfig/lion.kubeconfig

yaml文件

apiVersion: apps/v1
kind: Deployment #指定这是一个deployment
metadata:
  name: apollo-config-deploy #这里是deployment的名称
  namespace: public-c  # 这里是deployment所在的namespace
spec:
  replicas: 1 #需要启动几个副本
  selector:
    matchLabels:
      app: apollo-config #需要管理的pod的名称
  template: #模板
    metadata:
      labels:
        app: apollo-config #pod名称
    spec:
      containers:
      - name: apollo-config #pod名称
        image: harbortest.picchealth.com/lion_test/apollo-configservice:1.5.0 #容器的镜像
        ports:
        - containerPort: 8080 #端口
          name: httpport
        resources:
          limits:
            cpu: 200m #每一个pod的限制
            memory: 512Mi #每一个pod的限制
          requests:
            cpu: 50m #初始值
            memory: 128Mi #初始值
        volumeMounts:  # 使用,挂载volume ,使用下面的配置卷
        - name: config-volume #配置卷名称
          mountPath: /apollo-configservice/config #从configmap中加载的数据信息,到哪里
        - name: logs-storage
          mountPath: /opt/logs
      volumes:
      - name: config-volume # 随便定义一个volume NAME
        configMap: #这里是使用之前应用的configmap
          name: apollo-config-configmap  # 对应configmap NAME
      - name: logs-storage
        nfs:
            path: /NFS/PUBLIC
            server: 10.252.20.27

---
#创建service
apiVersion: v1 
kind: Service
metadata:
  name: apollo-config-svc #service name
  namespace: public-c #service所在的命名空间
  labels:
    app: apollo-config-svc 
spec:
  selector:
    app: apollo-config #service所管理哪个 pod
  type: NodePort
  ports:
  - name: http
    port: 8080 #端口 
    targetPort: 8080 #pod的端口
    protocol: TCP
    nodePort: 30080

上面文档几个我都有加注释,有几个地方我要跟大家提一句

  • 加载configmap。apollo默认加载配置文件的地方,在apollo根目录下的config文件夹内。所以我们要加载configmap,指定文件加载到容器内的/apollo-configservice/config 文件夹下
  • 挂载nfs,其实在正式的业务service中,我们可以使用elk来收集日志,我之所以挂载了Nfs,主要是因为最开始配置的时候,由于写错了个字母,导致pod一直起不来,然后我又看不到应用日志,只能看到容器的启动日志,所以只能等K8s自动拉起Pod的时候,赶紧使用

      kubectl --kubeconfig ../kubeconfig/lion.kubeconfig exec -it -n public-c deploy/apollo-config-deploy sh
    

    命令,进入到容器内部,查看日志。非常非常的麻烦。所以我就临时的把日志挂载到了nfs上,然后通过本地挂载Nfs进行日志的查看。听起来虽然麻烦,但是非常好的解决了问题的所在

修改数据库 eureka路径

在ApolloConfigDB的ServerConfig中,修改eureka的地址为http://apollo-config-svc.public-c:8080/eureka/

启动apolloconfig

kubectl apply -f apolloconfig.yaml --kubeconfig ../kubeconfig/lion.kubeconfig

配置apollo-admin和apollo-portal

与上面的配置一样 apollo-admin-configmap:

apiVersion: v1
kind: ConfigMap #类型是configmap
metadata:
  name: apollo-admin-configmap #configMap的名称
  namespace: public-c #所属的命名空间
  labels:
    app: apollo-admin-configmap 
#实际内容
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://mysql-svc.public-c:3306/ApolloConfigDB?characterEncoding=utf8
    spring.datasource.username = lion
    spring.datasource.password = abcdefg

apollo-portal-configmap:

apiVersion: v1
kind: ConfigMap #类型是configmap
metadata:
  name: apollo-portal-configmap #configMap的名称
  namespace: public-c #所属的命名空间
  labels:
    app: apollo-portal-configmap 
#实际内容
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://mysql-svc.public-c:3306/ApolloPortalDB?characterEncoding=utf8
    spring.datasource.username = lion
    spring.datasource.password = abcdefg
  
  apollo-env.properties: |
    local.meta=
    dev.meta=
    fat.meta=http://apollo-config-svc.public-c:8080
    uat.meta=
    lpt.meta=
    pro.meta=

apollo-admin.yml

apiVersion: apps/v1
kind: Deployment #指定这是一个deployment
metadata:
  name: apollo-admin-deploy #这里是deployment的名称
  namespace: public-c  # 这里是deployment所在的namespace
spec:
  replicas: 1 #需要启动几个副本
  selector:
    matchLabels:
      app: apollo-admin #需要管理的pod的名称
  template: #模板
    metadata:
      labels:
        app: apollo-admin #pod名称
    spec:
      containers:
      - name: apollo-admin #pod名称
        image: harbortest.picchealth.com/lion_test/apollo-adminservice:1.5.0 #容器的镜像
        ports:
        - containerPort: 8090 #端口
          name: httpport
        resources:
          limits:
            cpu: 200m #每一个pod的限制
            memory: 512Mi #每一个pod的限制
          requests:
            cpu: 50m #初始值
            memory: 128Mi #初始值
        volumeMounts:  # 使用,挂载volume ,使用下面的配置卷
        - name: config-volume #配置卷名称
          mountPath: /apollo-adminservice/config #从configmap中加载的数据信息,到哪里
        - name: logs-storage
          mountPath: /opt/logs
      volumes:
      - name: config-volume # 随便定义一个volume NAME
        configMap: #这里是使用之前应用的configmap
          name: apollo-admin-configmap  # 对应configmap NAME
      - name: logs-storage
        nfs:
            path: /NFS/PUBLIC
            server: 10.252.20.27

---
#创建service
apiVersion: v1 
kind: Service
metadata:
  name: apollo-admin-svc #service name
  namespace: public-c #service所在的命名空间
  labels:
    app: apollo-admin-svc 
spec:
  selector:
    app: apollo-admin #service所管理哪个 pod
  type: NodePort
  ports:
  - name: http
    port: 8090 #端口 
    targetPort: 8090 #pod的端口
    protocol: TCP
    nodePort: 30090

apollo-portal.yml

apiVersion: apps/v1
kind: Deployment #指定这是一个deployment
metadata:
  name: apollo-portal-deploy #这里是deployment的名称
  namespace: public-c  # 这里是deployment所在的namespace
spec:
  replicas: 1 #需要启动几个副本
  selector:
    matchLabels:
      app: apollo-portal #需要管理的pod的名称
  template: #模板
    metadata:
      labels:
        app: apollo-portal #pod名称
    spec:
      containers:
      - name: apollo-portal #pod名称
        image: harbortest.picchealth.com/lion_test/apollo-portal:1.5.1 #容器的镜像
        ports:
        - containerPort: 8070 #端口
          name: httpport
        resources:
          limits:
            cpu: 300m #每一个pod的限制
            memory: 512Mi #每一个pod的限制
          requests:
            cpu: 50m #初始值
            memory: 128Mi #初始值
        volumeMounts:  # 使用,挂载volume ,使用下面的配置卷
        - name: config-volume #配置卷名称
          mountPath: /apollo-portal/config #从configmap中加载的数据信息,到哪里
        - name: logs-storage
          mountPath: /opt/logs
      volumes:
      - name: config-volume # 随便定义一个volume NAME
        configMap: #这里是使用之前应用的configmap
          name: apollo-portal-configmap  # 对应configmap NAME
      - name: logs-storage
        nfs:
            path: /NFS/PUBLIC
            server: 10.252.20.27

---
#创建service
apiVersion: v1 
kind: Service
metadata:
  name: apollo-portal-svc #service name
  namespace: public-c #service所在的命名空间
  labels:
    app: apollo-portal-svc 
spec:
  selector:
    app: apollo-portal #service所管理哪个 pod
  type: NodePort
  ports:
  - name: http
    port: 8070 #端口 
    targetPort: 8070 #pod的端口
    protocol: TCP
    nodePort: 30070