The document discusses deploying Swift microservices with Docker and Kubernetes. It covers building a Swift microservice into a Docker container, deploying the container with Kubernetes, and integrating resiliency features like health checks, circuit breakers, and monitoring. Key points include using Dockerfiles to package the application, Helm charts to deploy to Kubernetes, liveness probes to check service health, and circuit breakers to handle failures of downstream services.
9. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
10. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
11. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
12. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
FROM ibmcom/swift-ubuntu-runtime:4.0
# We can replace this port with what the user wants
EXPOSE 8080
# Install system level packages
# RUN apt-get update && apt-get dist-upgrade -y
# Add utils files
ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu-
docker/master/utils/run-utils.sh /swift-utils/run-utils.sh
ADD https://raw.githubusercontent.com/IBM-Swift/swift-ubuntu-
docker/master/utils/common-utils.sh /swift-utils/common-utils.sh
RUN chmod -R 555 /swift-utils
# Bundle application source & binaries
COPY . /swift-project
# Command to start Swift application
CMD [ "sh", "-c", "cd /swift-project && .build-ubuntu/release/
helium" ]
13. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Dockerfile
Dockerfile-tools
.dockerignore
Dockerfile
Dockerfile-tools
31. • Checks status of service
• Requires /health endpoint providing data
• Restarts service if not 200 OK
• Restarts service if no response
Microservice Health: Liveness Probes
32. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
33. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
34. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import LoggerAPI
func initializeHealthRoutes(app: App) {
app.router.get("/health") { request, response, _ in
let result = health.status.toSimpleDictionary()
if health.status.state == .UP {
try response.send(json: result).end()
} else {
try response.status(.serviceUnavailable).send(json:
result).end()
}
}
}
35. • Provides “fault tolerance” to an application
• Enables handling of failed downstream services
• Prevents repeated calls to failed services
• Provides alternative fallback function
• Integrates with monitoring
Microservice Resilience: Hystrix and CircuitBreaker
36. • Provides “fault tolerance” to an application
• Enables handling of failed downstream services
• Prevents repeated calls to failed services
• Provides alternative fallback function
• Integrates with monitoring
Microservice Resilience: Hystrix and CircuitBreaker
41. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
let circuitParameters = CircuitParameters(
timeout: 2000,
maxFailures: 2,
fallback: myFallback)
let request = RestRequest(method: .get, url: "/hello")
request.circuitParameters = circuitParameters
SwiftyRequest
42. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
let circuitParameters = CircuitParameters(
timeout: 2000,
maxFailures: 2,
fallback: myFallback)
let request = RestRequest(method: .get, url: "/hello")
request.circuitParameters = circuitParameters
SwiftyRequest
43. • Collects data from each enabled service
• Requires /metrics endpoint providing data
• Provides storage and correlation capabilities
• Provide customisable dashboard
• Integrates with Graphana, Graphite, etc
Microservice Metrics: Prometheus
44. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
45. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import LoggerAPI
import CloudEnvironment
import KituraContracts
import Health
public let projectPath = ConfigurationManager.BasePath.project.path
public let health = Health()
public class App {
let router = Router()
let cloudEnv = CloudEnv()
public init() throws {
}
func postInit() throws {
initializeMetrics(app: self)
initializeHealthRoutes(app: self)
}
public func run() throws {
try postInit()
Kitura.addHTTPServer(onPort: cloudEnv.port, with: router)
Kitura.run()
}
}
46. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
47.
48.
49. • ‘SwiftMetricsDash’ provides self-hosted monitoring
• Inbound and Outbound request performance
• Resource monitoring
• ++ Dispatch queue monitoring
• ++ profiling and flame graphs
Deep Analysis: ‘SwiftMetricsDash’
50. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
51. func add(_ a: Int,
to b: Int) -> Void
{
print(a + b)
}
let a = ”5”
let b = 3
Sources/*
Sources/Application/Application.swift
Sources/Application/Routes/Health.swift
Sources/Applicaton/Metrics.swift
Tests/*
Package.swift
README.md
.gitignore
Kitura
import Kitura
import SwiftMetrics
import SwiftMetricsDash
import SwiftMetricsPrometheus
import LoggerAPI
var swiftMetrics: SwiftMetrics?
var swiftMetricsDash: SwiftMetricsDash?
var swiftMetricsPrometheus: SwiftMetricsPrometheus?
func initializeMetrics(router: Router) {
do {
let metrics = try SwiftMetrics()
let dashboard = try SwiftMetricsDash(swiftMetricsInstance:
metrics, endpoint: router)
let prometheus = try
SwiftMetricsPrometheus(swiftMetricsInstance:
metrics, endpoint: router)
swiftMetrics = metrics
swiftMetricsDash = dashboard
swiftMetricsPrometheus = prometheus
Log.info("Initialized metrics.")
} catch {
Log.warning("Failed to initialize metrics: (error)")
}
}
56. Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
57. Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT
58. Config Fault Tolerance Health Check Health Metrics JWT Propagation
externalize configuration
to improve portability
build robust behavior to
cope with unexpected
failures
common format to
determine service
availability
common REST
endpoints for monitoring
service health
interoperable
authentication and role-
based access control
CloudEnvironment CircuitBreaker Health SwiftMetricsPrometheus Swift-JWT
ibm-cloud-env hystrix-js /health appmetrics-prometheus jsonwebtoken
59. 59
IBM Foundation
Support for Runtimes
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
Enterprise Support: Runtimes
60. 60
LoopBack
IBM Foundation
Support for Runtimes
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
IBM Advanced
Support for Runtime
Frameworks
Enterprise Support: Frameworks
61. 61
LoopBack
IBM Foundation
Support for Runtimes
IBM Advanced
Support for Runtime
Frameworks
generator-nodeserver
appmetrics monitoring
generator-swiftserver
swiftmetrics monitoringjavametrics monitoring
IBM Support for Runtimes
Enterprise Support: Module Ecosystems
63. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
64. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
65. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
66. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
67. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
68. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
69. PUBLIC NETWORK CLOUD NETWORK
CATALOG
ORDER
INVENTORY
USER
MySQL
MongoDB
SPARK
ELASTICSEARCH
BACKEND FOR
FRONTEND
MICROSERVICES SERVICES
LOAD
BALANCER
78. • Collects data from each enabled service
• Propagates correlation ID using HTTP headers
• Provides sampling, tracing, and debug capabilities
• Collects microsecond timestamps
• Correlates data in Zipkin server
• Presents data in Zipkin dashboard
Request Tracking: OpenTracing and Zipkin