परिचय: Swift और Kubernetes क्यों?
Swift केवल iOS और macOS के लिए भाषा नहीं है। Swift on Server प्रोजेक्ट और Vapor तथा SwiftNIO जैसे फ्रेमवर्क की बदौलत, Swift डेवलपर्स उच्च-प्रदर्शन वाले सर्वर एप्लिकेशन बना सकते हैं। हालांकि, ऐसे एप्लिकेशन को स्थिर रूप से चलाने और स्केल करने के लिए आधुनिक बुनियादी ढांचे की आवश्यकता होती है।
Kubernetes (K8s) कंटेनर ऑर्केस्ट्रेशन के लिए डी-फैक्टो मानक है। इस गाइड में, हम दिखाएंगे कि कैसे Swift एप्लिकेशन को Docker-इमेज में पैक करें, Kubernetes के लिए मैनिफेस्ट लिखें और इसे क्लस्टर में डिप्लॉय करें। आप सीखेंगे कि हल्का HTTP-सर्वर बनाने के लिए SwiftNIO का उपयोग कैसे करें और इसे क्लाउड में काम करने के लिए कैसे कॉन्फ़िगर करें।
1. कंटेनरीकरण के लिए Swift-एप्लिकेशन तैयार करना
1.1. SwiftNIO पर प्रोजेक्ट बनाना
प्रदर्शन के लिए, हम SwiftNIO पर एक न्यूनतम HTTP-सर्वर लिखेंगे। यह अनावश्यक निर्भरताओं से बचाएगा और दिखाएगा कि निम्न-स्तरीय नेटवर्किंग कैसे काम करती है। टर्मिनल खोलें और एक नया प्रोजेक्ट बनाएं:
mkdir SwiftK8sDemocd SwiftK8sDemoswift package init --type executablePackage.swift में SwiftNIO निर्भरता जोड़ें:
// swift-tools-version:5.7import PackageDescription
let package = Package( name: "SwiftK8sDemo", dependencies: [ .package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0") ], targets: [ .executableTarget( name: "SwiftK8sDemo", dependencies: [ .product(name: "NIO", package: "swift-nio"), .product(name: "NIOHTTP1", package: "swift-nio") ] ) ])1.2. हेल्थ चेक के साथ सर्वर कोड
हम एक सरल सर्वर बनाएंगे जो GET अनुरोधों का जवाब देता है और स्वास्थ्य जांच (/health) के लिए एंडपॉइंट रखता है। यह Kubernetes liveness probe के लिए आवश्यक है। Sources/SwiftK8sDemo/main.swift की सामग्री बदलें:
import NIOimport NIOHTTP1
final class HTTPHandler: ChannelInboundHandler { typealias InboundIn = HTTPServerRequestPart typealias OutboundOut = HTTPServerResponsePart
func channelRead(context: ChannelHandlerContext, data: NIOAny) { let req = unwrapInboundIn(data) switch req { case .head(let header): let response: String let status: HTTPResponseStatus if header.uri == "/health" { response = "{\\"status\\":\\"ok\\"}" status = .ok } else { response = "Hello from Swift on K8s!" status = .ok } var buffer = context.channel.allocator.buffer(capacity: response.utf8.count) buffer.writeString(response) let head = HTTPResponseHead(version: .init(major: 1, minor: 1), status: status) context.write(wrapOutboundOut(.head(head)), promise: nil) context.write(wrapOutboundOut(.body(.byteBuffer(buffer))), promise: nil) context.writeAndFlush(wrapOutboundOut(.end(nil)), promise: nil) default: break } }}
let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)defer { try! group.syncShutdownGracefully() }
let bootstrap = ServerBootstrap(group: group) .serverChannelOption(ChannelOptions.backlog, value: 256) .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) .childChannelInitializer { channel in channel.pipeline.configureHTTPServerPipeline().flatMap { channel.pipeline.addHandler(HTTPHandler()) } }
let host = ProcessInfo.processInfo.environment["HOST"] ?? "0.0.0.0"let port = Int(ProcessInfo.processInfo.environment["PORT"] ?? "8080") ?? 8080
print("Server starting on \\(host):\\(port)")try bootstrap.bind(host: host, port: port).wai