前言 前段时间搭建了跨公有云厂商的k3s集群,部署了几个比较小的服务来测试一些稳定性。
结果还是有些让人失望的,跨越地域传输数据的网络的稳定性还是比较差,经常出现服务无法访问的情况,在网上也找了很多用其他软件构建虚拟内网的文档,试着搭建了一下,发现稳定性还是很脆弱。
奈何暂时放弃了使用公有云集群作为自己的生产k8s集群的方案,比较生产集群稳定性还是有一定要求,我自己自建了很多的服务,包括
spug 云上ssh工具,可以管理云主机,在必要的时候连接到云主机
bitwarden 非常好用而且开源的密码管理器,我现在的各种网站的密码都是使用的随机密码,大大降低了数据泄露的风险
outline 文档管理工具,自建的wiki,这篇文章就是使用outline写的
linkace 书签管理器
这篇文章叫《公有云安装k3s集群实践(二)》,实际上应该是《k3s公有云集群从入门到放弃》。
基于多方面考虑,直接搭建单节点k3s,把原来的k3s卸载,然后直接重新安装k3s,就能直接使用了。
1 2 3 4 5 6 7 8 /usr/local/bin/k3s-uninstall.sh /usr/local/bin/k3s-agent-uninstall.sh curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - server --disable traefik --docker --tls-san 公网IP
那我这篇文章要说什么呢?主要是讲一下我如何从docker-compose的服务管理,迁移到k8s的服务管理。
对比docker-compose、k8s服务管理的些许不同 比对不同主要是从我自身的角度出发,作为个人开发者,在实际使用上的不同来进行简单的对比:
docker-compose是单机模式,部署服务需要连接到对应的云主机,然后执行命令,它最大的作用是记住一些关键配置,不需要每次都docker run -d -p 8080:80 -v xxx:xxx nginx
和能让容器有多副本,仅此而已
k8s服务作为容器编排的top1,主要是足够的自动化,外部的devops只需要获取到k8s集群的kubeconfig
就能够访问到k8s集群进行服务部署,就是配置服务文件会有一些门槛,但是经过了使用可视化的web界面来实践之后,直接把对应的deloyment.yaml
文件拿下来改改就能够构建其他的服务,相比来说更灵活也更简单
从docker-compose迁移到k8s 目前k8s有提供工具来从docker-compose.yaml
文件转化为k8s运行需要的yaml文件,但是仍然需要做些许修改才能正常使用。
安装kompose 1 2 3 4 5 6 7 8 9 10 11 curl -L https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose-linux-amd64 -o kompose curl -L https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose-darwin-amd64 -o kompose chmod +x komposesudo mv ./kompose /usr/local/bin/kompose
以linkace服务为例转化为k8s服务 linkace 的docker-compose.yaml
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 --- version: '3.3' services: link: image: linkace/linkace:${LINKACE_VERSION} networks: - gateway container_name: link restart: unless-stopped env_file: .env volumes: - ./.env:/app/.env - /data/logs/link/logs:/app/storage/logs - /data/logs/link/backups:/app/storage/app/backups healthcheck: disable: false environment: - TZ=Asia/Shanghai ports: - 2022 :80 networks: gateway: external: true ...
linkace 的.env
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 LINKACE_VERSION=v1.10.4-php-nginx COMPOSE_PROJECT_NAME=linkace APP_KEY= DB_CONNECTION=mysql DB_HOST=mysql-host DB_PORT=3306 DB_DATABASE=database DB_USERNAME=username DB_PASSWORD=password REDIS_HOST=host REDIS_PASSWORD= REDIS_PORT=6379 SESSION_DRIVER=redis LOG_CHANNEL=stack BROADCAST_DRIVER=log CACHE_DRIVER=redis QUEUE_DRIVER=database
可以看出结构非常的简单,我比较关心的主要是两个点
volumes
原来我的数据都是挂在宿主机上的,方便迁移到其他的机器
.env
我的.env中存储的是容器运行所需的环境变量
转化为k8s可执行文件
1 2 3 4 5 6 7 8 9 10 11 kompose convert -f linkace/ link-deployment.yaml link-service.yaml env-configmap.yaml gateway-networkpolicy.yaml link-claim0-persistentvolumeclaim.yaml link-claim1-persistentvolumeclaim.yaml link-claim2-persistentvolumeclaim.yaml
当看到一个简单的docker-compose.yaml
文件通过kompose转化为7个文件的时候我还是有点震惊的,正常情况下只需要两个文件即可:deployment.yaml
、service.yaml
开始手动修改link-deployment.yaml
文件让它变得更简单
生成的link-deployment.yaml
文件内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yaml kompose.version: 1.26 .1 (a9d05d509) creationTimestamp: null labels: io.kompose.service: link name: link spec: replicas: 1 selector: matchLabels: io.kompose.service: link strategy: type: Recreate template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yaml kompose.version: 1.26 .1 (a9d05d509) creationTimestamp: null labels: io.kompose.network/gateway: "true" io.kompose.service: link spec: containers: - env: - name: APP_KEY valueFrom: configMapKeyRef: key: APP_KEY name: env ...#中间省略一大块 env的内容 - name: TZ value: Asia/Shanghai image: 'linkace/linkace:' name: link ports: - containerPort: 80 resources: {} volumeMounts: - mountPath: /app/.env name: link-claim0 - mountPath: /app/storage/logs name: link-claim1 - mountPath: /app/storage/app/backups name: link-claim2 restartPolicy: Always volumes: - name: link-claim0 persistentVolumeClaim: claimName: link-claim0 - name: link-claim1 persistentVolumeClaim: claimName: link-claim1 - name: link-claim2 persistentVolumeClaim: claimName: link-claim2 status: {}
修改完的link-deployment.yaml
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 apiVersion: apps/v1 kind: Deployment metadata: name: link-app namespace: cloud-app labels: app: link-app annotations: deployment.kubernetes.io/revision: '1' kubesphere.io/creator: flow spec: replicas: 1 selector: matchLabels: app: link-app strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 25 % maxSurge: 25 % template: metadata: labels: app: link-app spec: containers: - env: - name: APP_KEY valueFrom: configMapKeyRef: key: APP_KEY name: link-env ...#省略一大堆的配置 - name: TZ value: Asia/Shanghai image: 'linkace/linkace:v1.10.4-php-nginx' name: link-app ports: - name: tcp-80 containerPort: 80 protocol: TCP resources: {} volumeMounts: - mountPath: /app/storage/logs name: link-logs - mountPath: /app/storage/app/backups name: link-backups imagePullPolicy: IfNotPresent restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst serviceAccountName: default serviceAccount: default securityContext: {} imagePullSecrets: - name: aliyun-docker schedulerName: default-scheduler volumes: - name: link-logs hostPath: path: /data/link/logs type: DirectoryOrCreate - name: link-backups hostPath: path: /data/link/backups type: DirectoryOrCreate revisionHistoryLimit: 10 progressDeadlineSeconds: 600 --- kind: ConfigMap apiVersion: v1 metadata: name: link-env namespace: cloud-app labels: app: link-env annotations: kubesphere.io/creator: flow data: APP_KEY: BROADCAST_DRIVER: log CACHE_DRIVER: redis COMPOSE_PROJECT_NAME: linkace DB_CONNECTION: mysql DB_DATABASE: linkace DB_HOST: host DB_PASSWORD: password DB_PORT: "3306" DB_USERNAME: xxxx LINKACE_VERSION: v1.10.4-php-nginx LOG_CHANNEL: stack QUEUE_DRIVER: database REDIS_HOST: redis-host REDIS_PASSWORD: REDIS_PORT: "6379" SESSION_DRIVER: redis --- kind: Service apiVersion: v1 metadata: name: link-app-svc namespace: cloud-app labels: app: link-app-svc annotations: kubesphere.io/creator: flow spec: ports: - name: http-2008 protocol: TCP port: 80 targetPort: 80 nodePort: 2008 selector: app: link-app type: NodePort sessionAffinity: None externalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack
主要修改的内容:
metadata 原来的很多meta都是以kompose的数据来的,然后我直接将我现在在kubesphere上下载下来的deployment.yaml
为模板来修改
env
这里使用了env
来生成了一个ConfigMap
的配置,然后直接在dpeloyment.yaml
文件中引用,格式是这样的
1 2 3 4 5 6 7 8 9 - name: APP_KEY valueFrom: configMapKeyRef: key: APP_KEY name: link-env - name: APP_KEY value: xxxx
volumes 的修改稍稍的麻烦一些,但是差不了太多,只是因为使用的volumes需要挂载到host
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 volumeMounts: - mountPath: /app/storage/logs name: link-logs - mountPath: /app/storage/app/backups name: link-backups volumes: - name: link-logs hostPath: path: /data/link/logs type: DirectoryOrCreate - name: link-backups hostPath: path: /data/link/backups type: DirectoryOrCreate
注意:
hostPath.type
支持很多种文件,我这里主要是四种用法:
DirectoryOrCreate
文件夹,如果不存在则创建
Directory
文件夹,不存在则报错
FileOrCreate
文件,不存在则创建
File
文件,不存在则报错
volumes.name
要和上下对应,不然找不到
关注一下service.nodePort
是你要在宿主机暴露的port,直接根据IP:nodePort对外可访问
总结 实际在k8s集群的网络联通测试上花了很多的时间和精力,但是确实么有特别靠谱的方法,所以暂时妥协用k3s单节点集群,就这其实也解决了我的服务从docker-compose迁移到k8s的问题,我将其他的机器也同样装上k3s,那还是没有体验上的差别,差别只是节点不能跨机器部署,单节点故障会导致服务不可用,对于个人服务来说不是特别重要。
另外并没有放弃使用k8s集群来做一些学习研究的工作,所以我申请了鹏城生态 的安全可靠,免费公益服务器来搭建k8s集群,来继续进行研究。
后面会将我其他的服务都逐步迁移到k8s中来进行管理,并且挖掘k8s一些好用的有意思的功能来进行应用。
学习的路上没有止境,我一直认为学习是为了更好的工作和生活,自建的服务是,docker是,k8s也是,节省了很多的人力物力去处理各种各样复杂的现实问题。