由于使用到了阿里的 K8S 托管集群 ACK,于是想占便宜。想用到托管 master node 的 etcd 来保存数据。
结果是,未遂!!无法使用。
阿里有单独的配置管理服务,复杂化了,不想用。
那么解决方案就是,启动只有一个节点副本的 etcd pod,然后数据持久化到 OSS 的 S3 桶中。
一、实现etcd的单节点docker化
首先我们只想在测试环境中跑一个单节点的 etcd,还没有用到 k8s,做法如下:
#!/bin/bash
NODE1=172.18.31.33
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
#REGISTRY=gcr.io/etcd-development/etcd
docker run \
-p 2379:2379 \
-p 2380:2380 \
--volume=/data/etcd:/etcd-data \
--name etcd ${REGISTRY}:latest \
/usr/local/bin/etcd \
--data-dir=/etcd-data --name node1 \
--initial-advertise-peer-urls http://${NODE1}:2380 --listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://${NODE1}:2379 --listen-client-urls http://0.0.0.0:2379 \
--initial-cluster node1=http://${NODE1}:2380
如上就可以了,容器跑起来以后进入容器测试一下:
docker exec -it 425f26903466 /bin/sh
etcdctl -C http://127.0.0.1:2379 member list
c3511611548b7c7c: name=node1 peerURLs=http://172.18.31.33:2380 clientURLs=http://172.18.31.33:2379 isLeader=true
etcdctl ls --recursive /
这样一个单节点的 etcd 就弄好了,对外暴露的是 2379 和 2380 端口
二、实现 etcd 的单节点 k8s 化
首先编写一个deployment文件etcd-deploy.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: etcd-deploy
labels:
app: etcd
spec:
replicas: 1
selector:
matchLabels:
app: etcd
template:
metadata:
labels:
app: etcd
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:latest
ports:
- containerPort: 2379
name: client
protocol: TCP
- containerPort: 2380
name: server
protocol: TCP
command:
- /usr/local/bin/etcd
- --name
- etcd
- --initial-advertise-peer-urls
- http://etcd:2380
- --listen-peer-urls
- http://0.0.0.0:2380
- --listen-client-urls
- http://0.0.0.0:2379
- --advertise-client-urls
- http://etcd:2379
- --initial-cluster
- etcd=http://etcd:2380
- --data-dir
- /etcd-data
volumeMounts:
- mountPath: /etcd-data
name: etcd-data
lifecycle:
postStart:
exec:
command:
- "sh"
- "-c"
- >
echo "127.0.0.1 etcd" >> /etc/hosts;
volumes:
- name: etcd-data
persistentVolumeClaim:
claimName: k8s-etcd-20g
restartPolicy: Always
注意上面,我们使用了一个 pvc 卷 k8s-etcd-20g,这个卷挂在 /etcd-data,是由 OSS 建立的,用于持久话数据,省得重启 etcd 的 pod,数据消失不见了。
然后,我们需要把这个 deployment 作为 svc 服务暴露在集群中,再编写一个etcd-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: etcd-svc
spec:
ports:
- port: 2379
name: tcp2379
protocol: TCP
targetPort: 2379
- port: 2380
name: tcp2380
protocol: TCP
targetPort: 2380
selector:
app: etcd
type: ClusterIP
kubectl apply 部署到 k8s 中,这样就可以了。
k8s测试方法,随便启动一个 busybox pod,进去测试一下:
kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm
curl http://etcd-svc:2379/version
curl http://etcd-svc.default:2379/version
curl http://etcd-svc.default:2379/v2/keys
curl http://etcd-svc.default:2379/v2/keys/?recursive=true
curl http://etcd-svc.default:2379/v2/keys/service/nginx
curl http://etcd-svc.default:2379/v2/keys/service/nginx/127.0.0.1
curl --location --request PUT 'http://etcd-svc:2379/v2/keys/service/nginx/10.240.0.41' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'value=10.240.0.41:9000'
curl http://etcd-svc.default:2379/v2/keys/service/nginx/