本系列链接:
- Istio源码系列1:pilot-agent 源码分析
- Istio源码系列2:citadel 源码分析
- Istio源码系列3:pilot-discovery 源码分析
- Istio源码系列4:mixer 源码分析
安全整体架构
 From: Istio 安全
源码位于 security,编译后名称为 citadel。
命令行介绍
Dockerfile istio.io/istio/security/docker/Dockerfile.citadel
| 1 | FROM scratch | 
查看版本:
| 1 | # kubectl exec -ti istio-citadel-55cdfdd57c-bh7dk -n istio-system -- /usr/local/bin/istio_ca version | 
命令行帮助:
| 1 | # kubectl exec -ti istio-citadel-55cdfdd57c-bh7dk -n istio-system -- /usr/local/bin/istio_ca --help | 
容器内部启动添加的命令行如下:
| 1 | - --append-dns-names=true | 
可以在其运行的 node 节点上通过命令查看
| 1 | $ /usr/local/bin/istio_ca --self-signed-ca --append-dns-names=true --grpc-port=8060 --grpc-hostname=citadel --citadel-storage-namespace=istio-system --custom-dns-names=istio-pilot-service-account.istio-system:istio-pilot.istio-system,istio-ingressgateway-service-account.istio-system:istio-ingressgateway.istio-system --self-signed-ca=true | 
istio-citadel 启动的 yaml 文件
| 1 | # kubectl get pod istio-citadel-55cdfdd57c-bh7dk -n istio-system -o yaml | 
代码流程分析
整体架构

istio.io/istio/security/cmd/istio_ca/main.go
| 1 | // /usr/local/bin/istio_ca | 
runCA 的主函数流程如下:
| 1 | func runCA() { | 
NewSecretController
SecretController 内部会创建两个 Controller:
- ServiceAccount 的监听,如果设置了 listened-namespace,则监听该 namespace 下,否则是全部;
- Secret 的监听,namespace 同上,但是 Controller 只会监听自己创建的类型,即:type:”istio.io/key-and-cert”
实现的主要功能是为 ServiceAccount 创建对应的 Secret,Secret 中设置了相关的证书,在对应的 Pod 启动的时候进行加载;
| 1 | // NewSecretController returns a pointer to a newly constructed SecretController instance. | 
gRPC Server 启动
如果设置了 gRPC 相关的参数,则会启动相关的服务,同上也会启动两个 Controller 和 一个 gRPC Server,Controller 监听的 namespace 由 listened-namespace 设置,同上:
- NewServiceController:用于监听添加了注解 - alpha.istio.io/kubernetes-serviceaccounts和- alpha.istio.io/canonical-serviceaccounts的 Service 对象;从注解中解出来对应的用户名对应的 Reg 注册表的映射关系中,当前 key 和 value 都是相同- c.reg.AddMapping(svcAcct, svcAcct);- istio.io/istio/security/pkg/registry/kube/service.go - 1 
 2
 3
 4
 5
 6
 7- // KubeServiceAccountsOnVMAnnotation is to specify the K8s service accounts that are allowed to run 
 // this service on the VMs
 KubeServiceAccountsOnVMAnnotation = "alpha.istio.io/kubernetes-serviceaccounts"
 
 // CanonicalServiceAccountsAnnotation is to specify the non-Kubernetes service accounts that
 // are allowed to run this service.
 CanonicalServiceAccountsAnnotation = "alpha.istio.io/canonical-serviceaccounts"- 结构体定义如下: - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- // ServiceController monitors the service definition changes in a namespace. If a 
 // new service is added with "alpha.istio.io/kubernetes-serviceaccounts" or
 // "alpha.istio.io/canonical-serviceaccounts" annotations enabled,
 // the corresponding service account will be added to the identity registry
 // for whitelisting.
 type ServiceController struct {
 core corev1.CoreV1Interface
 // identity registry object
 reg registry.Registry
 // controller for service objects
 controller cache.Controller
 }
- NewServiceAccountController: 监听 ServiceAccount 对象;对于获取到 sa 信息,生成相对应的 - SpiffeID保存到 Reg 注册表的映射关系中,当前 key 和 value 都是相同- c.reg.DeleteMapping(id, id);- 结构体定义如下: - istio.io/istio/security/pkg/registry/kube/serviceaccount.go - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- // ServiceAccountController monitors service account definition changes in a namespace. 
 // For each service account object, its SpiffeID is added to identity registry for
 // whitelisting purpose.
 type ServiceAccountController struct {
 core corev1.CoreV1Interface
 // identity registry object
 reg registry.Registry
 // controller for service objects
 controller cache.Controller
 }
- IstioCAServiceServer:主要提供证书的生成和验证功能; - istio.io/istio/security/pkg/server/ca/server.go - 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- // CreateCertificate handles an incoming certificate signing request (CSR). It does 
 // authentication and authorization. Upon validated, signs a certificate that:
 // the SAN is the identity of the caller in authentication result.
 // the subject public key is the public key in the CSR.
 // the validity duration is the ValidityDuration in request, or default value if the given duration is invalid.
 // it is signed by the CA signing key.
 func (s *Server) CreateCertificate(ctx context.Context, request *pb.IstioCertificateRequest) (
 *pb.IstioCertificateResponse, error) {
 
 // 根据请求生成对应的证书
 _, _, certChainBytes, rootCertBytes := s.ca.GetCAKeyCertBundle().GetAll()
 cert, signErr := s.ca.Sign(
 []byte(request.Csr), caller.Identities, time.Duration(request.ValidityDuration)*time.Second, false)
 respCertChain := []string{string(cert)}
 respCertChain = append(respCertChain, string(rootCertBytes))
 response := &pb.IstioCertificateResponse{
 CertChain: respCertChain,
 }
 log.Debug("CSR successfully signed.")
 return response, nil
 }
 // HandleCSR handles an incoming certificate signing request (CSR). It does
 // proper validation (e.g. authentication) and upon validated, signs the CSR
 // and returns the resulting certificate. If not approved, reason for refusal
 // to sign is returned as part of the response object.
 // [TODO](myidpt): Deprecate this function.
 func (s *Server) HandleCSR(ctx context.Context, request *pb.CsrRequest) (*pb.CsrResponse, error) {
 csr, err := util.ParsePemEncodedCSR(request.CsrPem)
 _, err = util.ExtractIDs(csr.Extensions)
 // TODO: Call authorizer.
 _, _, certChainBytes, _ := s.ca.GetCAKeyCertBundle().GetAll()
 cert, signErr := s.ca.Sign(request.CsrPem, []string{}, time.Duration(request.RequestedTtlMinutes)*time.Minute, s.forCA)
 response := &pb.CsrResponse{
 IsApproved: true,
 SignedCert: cert,
 CertChain: certChainBytes,
 }
 log.Debug("CSR successfully signed.")
 return response, nil
 }
Monitor
   Monitor 服务主要用于对外输出检查,为 HttpServer, 主要提供 /metrics 和 /version ,如果启用了 enableProfiling 还会启用 /debug/pprof/ 相关的路径;当 Monitor 启动以后, Citadel 则任务已经启动成功,打印以下信息:log.Info("Citadel has started");
CA client
如果指定了 upstream CA Server,还会启动一个 CA Client, 创建一个 rotator go routine,定期用于证书的轮转替换;
istio.io/istio/security/pkg/caclient/keycertbundlerotator.go
| 1 | // Start periodically rotates the KeyCertBundle by interacting with the upstream CA. | 
TODO: istio-security-post-install 和 istio-cleanup-secrets Job 作用
除特别声明本站文章均属原创(翻译内容除外),如需要转载请事先联系,转载需要注明作者原文链接地址。