如何让 Kerberos 身份验证在托管具有 SqlConnection 的 .Net 6 应用程序的 Docker Linux 容器中工作?
我正在使用 AutomatedLab 创建的一个小型实验室进行实验,其中包含运行 ActiveDirectory 和 SQLServer 的 Windows Server 2022 计算机以及运行 Kubernetes 集群的 CentOS 8.5 计算机。我的测试应用程序是一个 .Net 6 控制台应用程序,它只需通过可信连接连接到在实验室中运行的 SQLServer 数据库。它是基于官方的aspnet:6.0镜像进行容器化的。 Kubernetes POD 包含一个 InitContainer,它执行 kinit 以生成放置在共享卷中的 Kerberos 令牌。我制作了两个版本的测试应用程序:第一个版本使用 OdbcConnection 连接到数据库,第二个版本使用 SqlConnection。使用 OdbcConnection 的版本成功连接到数据库,但使用 SqlConnection 的版本在打开与数据库的连接时崩溃。
以下是使用 OdbcConnection 的应用程序的代码:
using (var connection =
new OdbcConnection(
"Driver={ODBC Driver 17 for SQL Server};Server=sql1.contoso.com,1433;Database=KubeDemo;Trusted_Connection=Yes;"))
{
Log.Information("connection created");
var command = new OdbcCommand
("select * from KubeDemo.dbo.Test", connection);
connection.Open();
Log.Information("Connection opened");
using (var reader = command.ExecuteReader())
{
Log.Information("Read");
while (reader.Read())
{
Console.WriteLine($"{reader[0]}");
}
}
}
容器的日志显示它可以连接到数据库并读取其内容
[16:24:35 INF] Starting the application
[16:24:35 INF] connection created
[16:24:35 INF] Connection opened
[16:24:35 INF] Read
1
以下是使用 SqlConnection 的应用程序的代码:
using (var connection =
new SqlConnection(
"Server=sql1.contoso.com,1433;Initial Catalog=KubeDemo;Integrated Security=True;"))
{
Log.Information("connection created");
var command = new SqlCommand
("select * from KubeDemo.dbo.Test", connection);
connection.Open();
Log.Information("Connection opened");
using (var reader = command.ExecuteReader())
{
Log.Information("Read");
while (reader.Read())
{
Console.WriteLine($"{reader[0]}");
}
}
}
容器崩溃,根据连接时的日志正在打开:
[16:29:58 INF] Starting the application
[16:29:58 INF] connection created
我已经使用命令“tail -f /dev/null”部署了 Kubernetes pod,以便我可以手动执行应用程序,并且我得到了额外的一行:
[16:29:58 INF] Starting the application
[16:29:58 INF] connection created
Segmentation fault (core dumped)
根据 Google,这是指示尝试的 C++ 错误消息访问未经授权的内存 部分。不幸的是我不知道如何解决这个问题。有谁知道如何让它发挥作用?
为了完整起见,以下是容器化应用程序的 Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install curl gnupg2 -y
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install --assume-yes --no-install-recommends --allow-unauthenticated unixodbc msodbcsql17 mssql-tools
RUN apt-get remove curl gnupg2 -y
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
WORKDIR /app
EXPOSE 80
COPY ./ .
ENTRYPOINT ["dotnet", "DbTest.dll"]
和 POD Helm 模板:
apiVersion: v1
kind: Pod
metadata:
name: dbtest
labels:
app: test
spec:
restartPolicy: Never
volumes:
- name: kbr5-cache
emptyDir:
medium: Memory
- name: keytab-dir
secret:
secretName: back01-keytab
defaultMode: 0444
- name: krb5-conf
configMap:
name: krb5-conf
defaultMode: 0444
initContainers:
- name: kerberos-init
image: gambyseb/private:kerberos-init-0.2.0
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
env:
- name: KRB5_CONFIG
value: /krb5
volumeMounts:
- name: kbr5-cache
mountPath: /dev/shm
- name: keytab-dir
mountPath: /keytab
- name: krb5-conf
mountPath: /krb5
containers:
- name: dbtest
image: {{ .Values.image.repository }}:DbTest-{{ .Chart.AppVersion }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: ASPNETCORE_ENVIRONMENT
value: "{{ .Values.environment.ASPNETCORE }}"
- name: KRB5_CONFIG
value: /krb5
{{/* command:*/}}
{{/* - "tail"*/}}
{{/* - "-f"*/}}
{{/* - "/dev/null"*/}}
securityContext:
allowPrivilegeEscalation: true
privileged: true
ports:
- containerPort: 80
volumeMounts:
- name: kbr5-cache
mountPath: /dev/shm
- name: krb5-conf
mountPath: /krb5
- name: keytab-dir
mountPath: /keytab
{{/* - name: kerberos-refresh*/}}
{{/* image: gambyseb/private:kerberos-refresh-0.1.0*/}}
{{/* imagePullPolicy: {{ .Values.image.pullPolicy }}*/}}
{{/* env:*/}}
{{/* - name: KRB5_CONFIG*/}}
{{/* value: /krb5*/}}
{{/* volumeMounts:*/}}
{{/* - name: kbr5-cache*/}}
{{/* mountPath: /dev/shm*/}}
{{/* - name: keytab-dir*/}}
{{/* mountPath: /keytab*/}}
{{/* - name: krb5-conf*/}}
{{/* mountPath: /krb5*/}}
imagePullSecrets:
- name: {{ .Values.image.pullSecret }}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这可能不会被重新加油。
如果要部署到Linux容器,则需要确保您不部署system.data.sqlclient,因为这是仅Windows库。当您首先加载库时,它将仅炸毁您的容器(如您所经历的)。
我发现,如果我添加了microsoft.data.sqlclient,它没有添加,但是我想我要离开dapper或ef来添加依赖关系,并且它以system.data.sqlclient为单位。随着容器在AWS中炸毁,我几乎没有关于原因的反馈!
请参阅
This may not be Auth reated.
If you are deploying to a linux container you need to make sure you don't deploy System.Data.SqlClient as this is a Windows only library. It will just blow up your container (as you are experiencing) when it first loads the library.
I found that if I added Microsoft.Data.SqlClient it didn't get added but I think I was leaving Dapper or EF to add the dependency and it went into the release as System.Data.SqlClient. As the container blew up in AWS I had very little feedback as to the cause!
See https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/