k8s 部署ETCD ,并且使用.net core 连接获取配置
- 创建namespace
sudo kubectl create namespace compose
- 部署ETCD
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: etcd
namespace: compose
labels:
app: etcd
spec:
serviceName: etcd
replicas: 1
selector:
matchLabels:
app: etcd
template:
metadata:
labels:
app: etcd
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.4.15
ports:
- containerPort: 2379
- containerPort: 2380
command:
- /usr/local/bin/etcd
- --data-dir=/var/lib/etcd
- --name=$(POD_NAME)
- --listen-peer-urls=http://0.0.0.0:2380
- --listen-client-urls=http://0.0.0.0:2379
- --advertise-client-urls=http://$(POD_IP):2379
- --initial-advertise-peer-urls=http://$(POD_IP):2380
- --initial-cluster=$(POD_NAME)=http://$(POD_IP):2380
- --initial-cluster-token=etcd-cluster
- --initial-cluster-state=new
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- name: etcd-data
mountPath: /var/lib/etcd
volumeClaimTemplates:
- metadata:
name: etcd-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: etcd
namespace: compose
spec:
type: NodePort
ports:
- port: 2379
name: a-name
targetPort: 2379
nodePort: 30379
- port: 2380
name: b-name
targetPort: 2380
nodePort: 30380
selector:
app: etcd
- 进入pod添加root用户
# 使用 etcdctl 创建 root 用户
etcdctl user add root
# 系统会提示输入密码
# 创建一个管理员角色
etcdctl role add root
# 为 root 角色赋予读写权限
etcdctl role grant-permission root readwrite /
# 将 root 用户赋予 root 角色
etcdctl user grant-role root root
# 启用 etcd 的认证功能
etcdctl auth enable
- 创建普通用户
etcdctl user add user1
# 创建一个自定义角色
etcdctl role add readwrite
# 为该角色赋予读写权限,仅对指定路径(如 `/config/`)
etcdctl role grant-permission readwrite readwrite /config/
# 将用户赋予这个角色
etcdctl user grant-role user1 readwrite
# 以 user1 用户的身份操作 etcd
etcdctl --user=user1:password get /config/appsetting
- yaml 启用认证
command:
- etcd
- --auth-token=simple
- 安装dotnet-etcd
> dotnet-etcd 7.1.1 7.1.1
- 声明帮助类
using dotnet_etcd;
using Etcdserverpb;
using Google.Protobuf;
using Grpc.Core;
namespace coreETCD
{
public class ETCDHelper
{
private readonly EtcdClient etcdClient;
private AuthenticateResponse authenticateResponse;
public ETCDHelper()
{
etcdClient = new EtcdClient("http://192.168.214.133:30379", configureChannelOptions: (options =>
{
options.Credentials = ChannelCredentials.Insecure;
}));
authenticateResponse = etcdClient.Authenticate(new Etcdserverpb.AuthenticateRequest()
{
Name = "ellis",
Password = "ellis",
});
// 观察字段CRUD时间
etcdClient.WatchAsync("name", print, new Grpc.Core.Metadata() {
new Grpc.Core.Metadata.Entry("token",authenticateResponse.Token)
});
}
public async Task<PutResponse> PutConfig(string key, string value)
{
return await etcdClient.PutAsync(key, value, new Grpc.Core.Metadata() {
new Grpc.Core.Metadata.Entry("token",authenticateResponse.Token)
});
}
public async Task<string> GetConfig(string key)
{
return await etcdClient.GetValAsync(key, new Grpc.Core.Metadata() {
new Grpc.Core.Metadata.Entry("token",authenticateResponse.Token)
});
}
public async Task<Dictionary<string,string>> GetRange(string key)
{
RangeResponse result = await etcdClient.GetRangeAsync(key, new Grpc.Core.Metadata() {
new Grpc.Core.Metadata.Entry("token",authenticateResponse.Token)
});
Dictionary<string, string> dict = new Dictionary<string, string>();
// 遍历并输出键值对
foreach (var kv in result.Kvs)
{
dict.Add(kv.Key.ToStringUtf8(), kv.Value.ToStringUtf8());
}
return dict;
}
public async Task<DeleteRangeResponse> DeleteKey(string key)
{
return await etcdClient.DeleteAsync(key, new Grpc.Core.Metadata() {
new Grpc.Core.Metadata.Entry("token",authenticateResponse.Token)
});
}
// ----------------------------------
// Print function that prints key and value from the minimal watch
// response data
private static void print(WatchEvent[] response)
{
foreach (WatchEvent e1 in response)
{
Console.WriteLine($"{e1.Key}:{e1.Value}:{e1.Type}");
}
}
}
}
- DI
builder.Services.AddSingleton<ETCDHelper>();
- controller
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace coreETCD.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ETCDController : ControllerBase
{
private readonly ETCDHelper _etcdHelper;
public ETCDController(ETCDHelper etcdHelper)
{
_etcdHelper = etcdHelper;
}
[HttpGet]
public async Task<IActionResult> GetValue([FromQuery] string key)
{
var value = _etcdHelper.GetConfig(key).Result;
return Ok(value);
}
[HttpGet]
public async Task<IActionResult> GetRangeValue([FromQuery] string key)
{
var value = _etcdHelper.GetRange(key).Result;
return Ok(value);
}
[HttpGet]
public async Task<IActionResult> PutValue([FromQuery] string key,[FromQuery] string value)
{
var result = _etcdHelper.PutConfig(key,value).Result;
return Ok(result);
}
[HttpDelete]
public async Task<IActionResult> DeleteKey([FromQuery] string key)
{
var result = _etcdHelper.DeleteKey(key).Result;
return Ok(result);
}
}
}
- 罗列etcd已经存储的配置
etcdctl --user=username:password get "" --prefix --keys-only
原文地址:https://blog.csdn.net/weixin_43632687/article/details/142493875
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!